|
@@ -1917,18 +1917,6 @@ static inline int input_available_p(struct tty_struct *tty, int poll)
|
|
|
return ldata->commit_head - ldata->read_tail >= amt;
|
|
|
}
|
|
|
|
|
|
-static inline int check_other_done(struct tty_struct *tty)
|
|
|
-{
|
|
|
- int done = test_bit(TTY_OTHER_DONE, &tty->flags);
|
|
|
- if (done) {
|
|
|
- /* paired with cmpxchg() in check_other_closed(); ensures
|
|
|
- * read buffer head index is not stale
|
|
|
- */
|
|
|
- smp_mb__after_atomic();
|
|
|
- }
|
|
|
- return done;
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* copy_from_read_buf - copy read data directly
|
|
|
* @tty: terminal device
|
|
@@ -2124,7 +2112,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
|
|
|
struct n_tty_data *ldata = tty->disc_data;
|
|
|
unsigned char __user *b = buf;
|
|
|
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
|
|
- int c, done;
|
|
|
+ int c;
|
|
|
int minimum, time;
|
|
|
ssize_t retval = 0;
|
|
|
long timeout;
|
|
@@ -2183,32 +2171,35 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- done = check_other_done(tty);
|
|
|
-
|
|
|
if (!input_available_p(tty, 0)) {
|
|
|
- if (done) {
|
|
|
- retval = -EIO;
|
|
|
- break;
|
|
|
- }
|
|
|
- if (tty_hung_up_p(file))
|
|
|
- break;
|
|
|
- if (!timeout)
|
|
|
- break;
|
|
|
- if (file->f_flags & O_NONBLOCK) {
|
|
|
- retval = -EAGAIN;
|
|
|
- break;
|
|
|
- }
|
|
|
- if (signal_pending(current)) {
|
|
|
- retval = -ERESTARTSYS;
|
|
|
- break;
|
|
|
- }
|
|
|
up_read(&tty->termios_rwsem);
|
|
|
+ tty_buffer_flush_work(tty->port);
|
|
|
+ down_read(&tty->termios_rwsem);
|
|
|
+ if (!input_available_p(tty, 0)) {
|
|
|
+ if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
|
|
|
+ retval = -EIO;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (tty_hung_up_p(file))
|
|
|
+ break;
|
|
|
+ if (!timeout)
|
|
|
+ break;
|
|
|
+ if (file->f_flags & O_NONBLOCK) {
|
|
|
+ retval = -EAGAIN;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (signal_pending(current)) {
|
|
|
+ retval = -ERESTARTSYS;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ up_read(&tty->termios_rwsem);
|
|
|
|
|
|
- timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
|
|
|
- timeout);
|
|
|
+ timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
|
|
|
+ timeout);
|
|
|
|
|
|
- down_read(&tty->termios_rwsem);
|
|
|
- continue;
|
|
|
+ down_read(&tty->termios_rwsem);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (ldata->icanon && !L_EXTPROC(tty)) {
|
|
@@ -2386,12 +2377,17 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
|
|
|
|
|
|
poll_wait(file, &tty->read_wait, wait);
|
|
|
poll_wait(file, &tty->write_wait, wait);
|
|
|
- if (check_other_done(tty))
|
|
|
- mask |= POLLHUP;
|
|
|
if (input_available_p(tty, 1))
|
|
|
mask |= POLLIN | POLLRDNORM;
|
|
|
+ else {
|
|
|
+ tty_buffer_flush_work(tty->port);
|
|
|
+ if (input_available_p(tty, 1))
|
|
|
+ mask |= POLLIN | POLLRDNORM;
|
|
|
+ }
|
|
|
if (tty->packet && tty->link->ctrl_status)
|
|
|
mask |= POLLPRI | POLLIN | POLLRDNORM;
|
|
|
+ if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
|
|
|
+ mask |= POLLHUP;
|
|
|
if (tty_hung_up_p(file))
|
|
|
mask |= POLLHUP;
|
|
|
if (tty->ops->write && !tty_is_writelocked(tty) &&
|