diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-14 15:23:32 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-14 15:23:32 -0800 |
commit | 37da7bbbe84fe9e8862940d3f9194fd27dce59bb (patch) | |
tree | 6c3fae910b4cfd4e2f9a1fdc035400cd4df78be3 /drivers/tty/n_tty.c | |
parent | e7cf773d431a63a2417902696fcc9e0ebdc83bbe (diff) | |
parent | dd63af108f0814f0b589659f4e55a7a5af3b7e53 (diff) |
Merge tag 'tty-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial driver updates from Greg KH:
"Here's the big tty/serial driver update for 3.19-rc1.
There are a number of TTY core changes/fixes in here from Peter Hurley
that have all been teted in linux-next for a long time now. There are
also the normal serial driver updates as well, full details in the
changelog below"
* tag 'tty-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (219 commits)
serial: pxa: hold port.lock when reporting modem line changes
tty-hvsi_lib: Deletion of an unnecessary check before the function call "tty_kref_put"
tty: Deletion of unnecessary checks before two function calls
n_tty: Fix read_buf race condition, increment read_head after pushing data
serial: of-serial: add PM suspend/resume support
Revert "serial: of-serial: add PM suspend/resume support"
Revert "serial: of-serial: fix up PM ops on no_console_suspend and port type"
serial: 8250: don't attempt a trylock if in sysrq
serial: core: Add big-endian iotype
serial: samsung: use port->fifosize instead of hardcoded values
serial: samsung: prefer to use fifosize from driver data
serial: samsung: fix style problems
serial: samsung: wait for transfer completion before clock disable
serial: icom: fix error return code
serial: tegra: clean up tty-flag assignments
serial: Fix io address assign flow with Fintek PCI-to-UART Product
serial: mxs-auart: fix tx_empty against shift register
serial: mxs-auart: fix gpio change detection on interrupt
serial: mxs-auart: Fix mxs_auart_set_ldisc()
serial: 8250_dw: Use 64-bit access for OCTEON.
...
Diffstat (limited to 'drivers/tty/n_tty.c')
-rw-r--r-- | drivers/tty/n_tty.c | 81 |
1 files changed, 37 insertions, 44 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 26f097f60b10..d2b496750d59 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -321,7 +321,8 @@ static void n_tty_check_unthrottle(struct tty_struct *tty) static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata) { - *read_buf_addr(ldata, ldata->read_head++) = c; + *read_buf_addr(ldata, ldata->read_head) = c; + ldata->read_head++; } /** @@ -351,13 +352,13 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty) { unsigned long flags; - spin_lock_irqsave(&tty->ctrl_lock, flags); if (tty->link->packet) { + spin_lock_irqsave(&tty->ctrl_lock, flags); tty->ctrl_status |= TIOCPKT_FLUSHREAD; + spin_unlock_irqrestore(&tty->ctrl_lock, flags); if (waitqueue_active(&tty->link->read_wait)) wake_up_interruptible(&tty->link->read_wait); } - spin_unlock_irqrestore(&tty->ctrl_lock, flags); } /** @@ -2128,7 +2129,6 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, int minimum, time; ssize_t retval = 0; long timeout; - unsigned long flags; int packet; c = job_control(tty, file); @@ -2174,10 +2174,10 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, unsigned char cs; if (b != buf) break; - spin_lock_irqsave(&tty->link->ctrl_lock, flags); + spin_lock_irq(&tty->link->ctrl_lock); cs = tty->link->ctrl_status; tty->link->ctrl_status = 0; - spin_unlock_irqrestore(&tty->link->ctrl_lock, flags); + spin_unlock_irq(&tty->link->ctrl_lock); if (tty_put_user(tty, cs, b++)) { retval = -EFAULT; b--; @@ -2193,45 +2193,29 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, if (!input_available_p(tty, 0)) { if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { - up_read(&tty->termios_rwsem); - tty_flush_to_ldisc(tty); - down_read(&tty->termios_rwsem); - if (!input_available_p(tty, 0)) { - retval = -EIO; - break; - } - } else { - 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; - } - n_tty_set_room(tty); - up_read(&tty->termios_rwsem); - - timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, - timeout); - - down_read(&tty->termios_rwsem); - continue; + retval = -EIO; + break; } - } - - /* Deal with packet mode. */ - if (packet && b == buf) { - if (tty_put_user(tty, TIOCPKT_DATA, b++)) { - retval = -EFAULT; - b--; + if (tty_hung_up_p(file)) + break; + if (!timeout) + break; + if (file->f_flags & O_NONBLOCK) { + retval = -EAGAIN; break; } - nr--; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + n_tty_set_room(tty); + up_read(&tty->termios_rwsem); + + timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, + timeout); + + down_read(&tty->termios_rwsem); + continue; } if (ldata->icanon && !L_EXTPROC(tty)) { @@ -2243,8 +2227,17 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, break; } else { int uncopied; - /* The copy function takes the read lock and handles - locking internally for this case */ + + /* Deal with packet mode. */ + if (packet && b == buf) { + if (tty_put_user(tty, TIOCPKT_DATA, b++)) { + retval = -EFAULT; + b--; + break; + } + nr--; + } + uncopied = copy_from_read_buf(tty, &b, &nr); uncopied += copy_from_read_buf(tty, &b, &nr); if (uncopied) { |