|
@@ -89,6 +89,7 @@ struct n_tty_data {
|
|
|
int read_head;
|
|
|
int read_tail;
|
|
|
int read_cnt;
|
|
|
+ int minimum_to_wake;
|
|
|
|
|
|
unsigned char *echo_buf;
|
|
|
unsigned int echo_pos;
|
|
@@ -1455,7 +1456,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|
|
|
|
|
n_tty_set_room(tty);
|
|
|
|
|
|
- if ((!ldata->icanon && (ldata->read_cnt >= tty->minimum_to_wake)) ||
|
|
|
+ if ((!ldata->icanon && (ldata->read_cnt >= ldata->minimum_to_wake)) ||
|
|
|
L_EXTPROC(tty)) {
|
|
|
kill_fasync(&tty->fasync, SIGIO, POLL_IN);
|
|
|
if (waitqueue_active(&tty->read_wait))
|
|
@@ -1636,7 +1637,7 @@ static int n_tty_open(struct tty_struct *tty)
|
|
|
tty->disc_data = ldata;
|
|
|
reset_buffer_flags(tty->disc_data);
|
|
|
ldata->column = 0;
|
|
|
- tty->minimum_to_wake = 1;
|
|
|
+ ldata->minimum_to_wake = 1;
|
|
|
tty->closing = 0;
|
|
|
/* indicate buffer work may resume */
|
|
|
clear_bit(TTY_LDISC_HALTED, &tty->flags);
|
|
@@ -1804,17 +1805,17 @@ do_it_again:
|
|
|
minimum = MIN_CHAR(tty);
|
|
|
if (minimum) {
|
|
|
if (time)
|
|
|
- tty->minimum_to_wake = 1;
|
|
|
+ ldata->minimum_to_wake = 1;
|
|
|
else if (!waitqueue_active(&tty->read_wait) ||
|
|
|
- (tty->minimum_to_wake > minimum))
|
|
|
- tty->minimum_to_wake = minimum;
|
|
|
+ (ldata->minimum_to_wake > minimum))
|
|
|
+ ldata->minimum_to_wake = minimum;
|
|
|
} else {
|
|
|
timeout = 0;
|
|
|
if (time) {
|
|
|
timeout = time;
|
|
|
time = 0;
|
|
|
}
|
|
|
- tty->minimum_to_wake = minimum = 1;
|
|
|
+ ldata->minimum_to_wake = minimum = 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1854,9 +1855,9 @@ do_it_again:
|
|
|
TASK_RUNNING. */
|
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
|
|
|
|
- if (((minimum - (b - buf)) < tty->minimum_to_wake) &&
|
|
|
+ if (((minimum - (b - buf)) < ldata->minimum_to_wake) &&
|
|
|
((minimum - (b - buf)) >= 1))
|
|
|
- tty->minimum_to_wake = (minimum - (b - buf));
|
|
|
+ ldata->minimum_to_wake = (minimum - (b - buf));
|
|
|
|
|
|
if (!input_available_p(tty, 0)) {
|
|
|
if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
|
|
@@ -1973,7 +1974,7 @@ do_it_again:
|
|
|
remove_wait_queue(&tty->read_wait, &wait);
|
|
|
|
|
|
if (!waitqueue_active(&tty->read_wait))
|
|
|
- tty->minimum_to_wake = minimum;
|
|
|
+ ldata->minimum_to_wake = minimum;
|
|
|
|
|
|
__set_current_state(TASK_RUNNING);
|
|
|
size = b - buf;
|
|
@@ -2105,6 +2106,7 @@ break_out:
|
|
|
static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
|
|
|
poll_table *wait)
|
|
|
{
|
|
|
+ struct n_tty_data *ldata = tty->disc_data;
|
|
|
unsigned int mask = 0;
|
|
|
|
|
|
poll_wait(file, &tty->read_wait, wait);
|
|
@@ -2119,9 +2121,9 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
|
|
|
mask |= POLLHUP;
|
|
|
if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) {
|
|
|
if (MIN_CHAR(tty) && !TIME_CHAR(tty))
|
|
|
- tty->minimum_to_wake = MIN_CHAR(tty);
|
|
|
+ ldata->minimum_to_wake = MIN_CHAR(tty);
|
|
|
else
|
|
|
- tty->minimum_to_wake = 1;
|
|
|
+ ldata->minimum_to_wake = 1;
|
|
|
}
|
|
|
if (tty->ops->write && !tty_is_writelocked(tty) &&
|
|
|
tty_chars_in_buffer(tty) < WAKEUP_CHARS &&
|
|
@@ -2169,6 +2171,18 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void n_tty_fasync(struct tty_struct *tty, int on)
|
|
|
+{
|
|
|
+ struct n_tty_data *ldata = tty->disc_data;
|
|
|
+
|
|
|
+ if (!waitqueue_active(&tty->read_wait)) {
|
|
|
+ if (on)
|
|
|
+ ldata->minimum_to_wake = 1;
|
|
|
+ else if (!tty->fasync)
|
|
|
+ ldata->minimum_to_wake = N_TTY_BUF_SIZE;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
struct tty_ldisc_ops tty_ldisc_N_TTY = {
|
|
|
.magic = TTY_LDISC_MAGIC,
|
|
|
.name = "n_tty",
|
|
@@ -2182,7 +2196,8 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = {
|
|
|
.set_termios = n_tty_set_termios,
|
|
|
.poll = n_tty_poll,
|
|
|
.receive_buf = n_tty_receive_buf,
|
|
|
- .write_wakeup = n_tty_write_wakeup
|
|
|
+ .write_wakeup = n_tty_write_wakeup,
|
|
|
+ .fasync = n_tty_fasync,
|
|
|
};
|
|
|
|
|
|
/**
|