summaryrefslogtreecommitdiffstats
path: root/drivers/tty/n_tty.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-20 20:57:27 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-20 20:57:27 -0700
commite10abc629f38efd9b6936cf3612583cc846104d9 (patch)
tree58fb8f6dba5d085d4b0352137d18faf7cfa47a69 /drivers/tty/n_tty.c
parent0eff4589c36edd03d50b835d0768b2c2ef3f20bd (diff)
parentd20bb59af64667a16f2468b54fc0adb2f824a3b6 (diff)
downloadop-kernel-dev-e10abc629f38efd9b6936cf3612583cc846104d9.zip
op-kernel-dev-e10abc629f38efd9b6936cf3612583cc846104d9.tar.gz
Merge tag 'tty-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty and serial driver updates from Greg KH: "Here's the large TTY and Serial driver update for 4.7-rc1. A few new serial drivers are added here, and Peter has fixed a bunch of long-standing bugs in the tty layer and serial drivers as normal. Full details in the shortlog. All of these have been in linux-next for a while with no reported issues" * tag 'tty-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (88 commits) MAINTAINERS: 8250: remove website reference serial: core: Fix port mutex assert if lockdep disabled serial: 8250_dw: fix wrong logic in dw8250_check_lcr() tty: vt, finish looping on duplicate tty: vt, return error when con_startup fails QE-UART: add "fsl,t1040-ucc-uart" to of_device_id serial: mctrl_gpio: Drop support for out1-gpios and out2-gpios serial: 8250dw: Add device HID for future AMD UART controller Fix OpenSSH pty regression on close serial: mctrl_gpio: add IRQ locking serial: 8250: Integrate Fintek into 8250_base serial: mps2-uart: add support for early console serial: mps2-uart: add MPS2 UART driver dt-bindings: document the MPS2 UART bindings serial: sirf: Use generic uart-has-rtscts DT property serial: sirf: Introduce helper variable struct device_node *np serial: mxs-auart: Use generic uart-has-rtscts DT property serial: imx: Use generic uart-has-rtscts DT property doc: DT: Add Generic Serial Device Tree Bindings serial: 8250: of: Make tegra_serial_handle_break() static ...
Diffstat (limited to 'drivers/tty/n_tty.c')
-rw-r--r--drivers/tty/n_tty.c70
1 files changed, 33 insertions, 37 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index fb76a7d..bdf0e6e 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -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) &&
OpenPOWER on IntegriCloud