aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2013-06-15 07:28:28 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-06-17 15:55:11 -0400
commitf6c8dbe6e50c6e5121d7b6644718207daa008221 (patch)
treef7200d98ecaa899fb2c83d6b58b88a20b302f936 /drivers/tty
parenta630fbfbb1beeffc5bbe542a7986bf2068874633 (diff)
n_tty: Encapsulate minimum_to_wake within N_TTY
minimum_to_wake is unique to N_TTY processing, and belongs in per-ldisc data. Add the ldisc method, ldisc_ops::fasync(), to notify line disciplines when signal-driven I/O is enabled or disabled. When enabled for N_TTY (by fcntl(F_SETFL, O_ASYNC)), blocking reader/polls will be woken for any readable input. When disabled, blocking reader/polls are not woken until the read buffer is full. Canonical mode (L_ICANON(tty), n_tty_data::icanon) is not affected by the minimum_to_wake setting. 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/n_tty.c39
-rw-r--r--drivers/tty/tty_io.c17
2 files changed, 36 insertions, 20 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index cdcdb0ea061a..f1806de69b18 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -89,6 +89,7 @@ struct n_tty_data {
89 int read_head; 89 int read_head;
90 int read_tail; 90 int read_tail;
91 int read_cnt; 91 int read_cnt;
92 int minimum_to_wake;
92 93
93 unsigned char *echo_buf; 94 unsigned char *echo_buf;
94 unsigned int echo_pos; 95 unsigned int echo_pos;
@@ -1455,7 +1456,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
1455 1456
1456 n_tty_set_room(tty); 1457 n_tty_set_room(tty);
1457 1458
1458 if ((!ldata->icanon && (ldata->read_cnt >= tty->minimum_to_wake)) || 1459 if ((!ldata->icanon && (ldata->read_cnt >= ldata->minimum_to_wake)) ||
1459 L_EXTPROC(tty)) { 1460 L_EXTPROC(tty)) {
1460 kill_fasync(&tty->fasync, SIGIO, POLL_IN); 1461 kill_fasync(&tty->fasync, SIGIO, POLL_IN);
1461 if (waitqueue_active(&tty->read_wait)) 1462 if (waitqueue_active(&tty->read_wait))
@@ -1636,7 +1637,7 @@ static int n_tty_open(struct tty_struct *tty)
1636 tty->disc_data = ldata; 1637 tty->disc_data = ldata;
1637 reset_buffer_flags(tty->disc_data); 1638 reset_buffer_flags(tty->disc_data);
1638 ldata->column = 0; 1639 ldata->column = 0;
1639 tty->minimum_to_wake = 1; 1640 ldata->minimum_to_wake = 1;
1640 tty->closing = 0; 1641 tty->closing = 0;
1641 /* indicate buffer work may resume */ 1642 /* indicate buffer work may resume */
1642 clear_bit(TTY_LDISC_HALTED, &tty->flags); 1643 clear_bit(TTY_LDISC_HALTED, &tty->flags);
@@ -1804,17 +1805,17 @@ do_it_again:
1804 minimum = MIN_CHAR(tty); 1805 minimum = MIN_CHAR(tty);
1805 if (minimum) { 1806 if (minimum) {
1806 if (time) 1807 if (time)
1807 tty->minimum_to_wake = 1; 1808 ldata->minimum_to_wake = 1;
1808 else if (!waitqueue_active(&tty->read_wait) || 1809 else if (!waitqueue_active(&tty->read_wait) ||
1809 (tty->minimum_to_wake > minimum)) 1810 (ldata->minimum_to_wake > minimum))
1810 tty->minimum_to_wake = minimum; 1811 ldata->minimum_to_wake = minimum;
1811 } else { 1812 } else {
1812 timeout = 0; 1813 timeout = 0;
1813 if (time) { 1814 if (time) {
1814 timeout = time; 1815 timeout = time;
1815 time = 0; 1816 time = 0;
1816 } 1817 }
1817 tty->minimum_to_wake = minimum = 1; 1818 ldata->minimum_to_wake = minimum = 1;
1818 } 1819 }
1819 } 1820 }
1820 1821
@@ -1854,9 +1855,9 @@ do_it_again:
1854 TASK_RUNNING. */ 1855 TASK_RUNNING. */
1855 set_current_state(TASK_INTERRUPTIBLE); 1856 set_current_state(TASK_INTERRUPTIBLE);
1856 1857
1857 if (((minimum - (b - buf)) < tty->minimum_to_wake) && 1858 if (((minimum - (b - buf)) < ldata->minimum_to_wake) &&
1858 ((minimum - (b - buf)) >= 1)) 1859 ((minimum - (b - buf)) >= 1))
1859 tty->minimum_to_wake = (minimum - (b - buf)); 1860 ldata->minimum_to_wake = (minimum - (b - buf));
1860 1861
1861 if (!input_available_p(tty, 0)) { 1862 if (!input_available_p(tty, 0)) {
1862 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { 1863 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
@@ -1973,7 +1974,7 @@ do_it_again:
1973 remove_wait_queue(&tty->read_wait, &wait); 1974 remove_wait_queue(&tty->read_wait, &wait);
1974 1975
1975 if (!waitqueue_active(&tty->read_wait)) 1976 if (!waitqueue_active(&tty->read_wait))
1976 tty->minimum_to_wake = minimum; 1977 ldata->minimum_to_wake = minimum;
1977 1978
1978 __set_current_state(TASK_RUNNING); 1979 __set_current_state(TASK_RUNNING);
1979 size = b - buf; 1980 size = b - buf;
@@ -2105,6 +2106,7 @@ break_out:
2105static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, 2106static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
2106 poll_table *wait) 2107 poll_table *wait)
2107{ 2108{
2109 struct n_tty_data *ldata = tty->disc_data;
2108 unsigned int mask = 0; 2110 unsigned int mask = 0;
2109 2111
2110 poll_wait(file, &tty->read_wait, wait); 2112 poll_wait(file, &tty->read_wait, wait);
@@ -2119,9 +2121,9 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
2119 mask |= POLLHUP; 2121 mask |= POLLHUP;
2120 if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) { 2122 if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) {
2121 if (MIN_CHAR(tty) && !TIME_CHAR(tty)) 2123 if (MIN_CHAR(tty) && !TIME_CHAR(tty))
2122 tty->minimum_to_wake = MIN_CHAR(tty); 2124 ldata->minimum_to_wake = MIN_CHAR(tty);
2123 else 2125 else
2124 tty->minimum_to_wake = 1; 2126 ldata->minimum_to_wake = 1;
2125 } 2127 }
2126 if (tty->ops->write && !tty_is_writelocked(tty) && 2128 if (tty->ops->write && !tty_is_writelocked(tty) &&
2127 tty_chars_in_buffer(tty) < WAKEUP_CHARS && 2129 tty_chars_in_buffer(tty) < WAKEUP_CHARS &&
@@ -2169,6 +2171,18 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
2169 } 2171 }
2170} 2172}
2171 2173
2174static void n_tty_fasync(struct tty_struct *tty, int on)
2175{
2176 struct n_tty_data *ldata = tty->disc_data;
2177
2178 if (!waitqueue_active(&tty->read_wait)) {
2179 if (on)
2180 ldata->minimum_to_wake = 1;
2181 else if (!tty->fasync)
2182 ldata->minimum_to_wake = N_TTY_BUF_SIZE;
2183 }
2184}
2185
2172struct tty_ldisc_ops tty_ldisc_N_TTY = { 2186struct tty_ldisc_ops tty_ldisc_N_TTY = {
2173 .magic = TTY_LDISC_MAGIC, 2187 .magic = TTY_LDISC_MAGIC,
2174 .name = "n_tty", 2188 .name = "n_tty",
@@ -2182,7 +2196,8 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = {
2182 .set_termios = n_tty_set_termios, 2196 .set_termios = n_tty_set_termios,
2183 .poll = n_tty_poll, 2197 .poll = n_tty_poll,
2184 .receive_buf = n_tty_receive_buf, 2198 .receive_buf = n_tty_receive_buf,
2185 .write_wakeup = n_tty_write_wakeup 2199 .write_wakeup = n_tty_write_wakeup,
2200 .fasync = n_tty_fasync,
2186}; 2201};
2187 2202
2188/** 2203/**
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 6464029e4860..bd88007fa6ea 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -2138,6 +2138,7 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait)
2138static int __tty_fasync(int fd, struct file *filp, int on) 2138static int __tty_fasync(int fd, struct file *filp, int on)
2139{ 2139{
2140 struct tty_struct *tty = file_tty(filp); 2140 struct tty_struct *tty = file_tty(filp);
2141 struct tty_ldisc *ldisc;
2141 unsigned long flags; 2142 unsigned long flags;
2142 int retval = 0; 2143 int retval = 0;
2143 2144
@@ -2148,11 +2149,17 @@ static int __tty_fasync(int fd, struct file *filp, int on)
2148 if (retval <= 0) 2149 if (retval <= 0)
2149 goto out; 2150 goto out;
2150 2151
2152 ldisc = tty_ldisc_ref(tty);
2153 if (ldisc) {
2154 if (ldisc->ops->fasync)
2155 ldisc->ops->fasync(tty, on);
2156 tty_ldisc_deref(ldisc);
2157 }
2158
2151 if (on) { 2159 if (on) {
2152 enum pid_type type; 2160 enum pid_type type;
2153 struct pid *pid; 2161 struct pid *pid;
2154 if (!waitqueue_active(&tty->read_wait)) 2162
2155 tty->minimum_to_wake = 1;
2156 spin_lock_irqsave(&tty->ctrl_lock, flags); 2163 spin_lock_irqsave(&tty->ctrl_lock, flags);
2157 if (tty->pgrp) { 2164 if (tty->pgrp) {
2158 pid = tty->pgrp; 2165 pid = tty->pgrp;
@@ -2165,13 +2172,7 @@ static int __tty_fasync(int fd, struct file *filp, int on)
2165 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 2172 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
2166 retval = __f_setown(filp, pid, type, 0); 2173 retval = __f_setown(filp, pid, type, 0);
2167 put_pid(pid); 2174 put_pid(pid);
2168 if (retval)
2169 goto out;
2170 } else {
2171 if (!tty->fasync && !waitqueue_active(&tty->read_wait))
2172 tty->minimum_to_wake = N_TTY_BUF_SIZE;
2173 } 2175 }
2174 retval = 0;
2175out: 2176out:
2176 return retval; 2177 return retval;
2177} 2178}