diff options
Diffstat (limited to 'drivers/tty/n_tty.c')
| -rw-r--r-- | drivers/tty/n_tty.c | 109 |
1 files changed, 48 insertions, 61 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 6af3f3a0b531..e6a0f5b40d0a 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -324,12 +324,9 @@ static void reset_buffer_flags(struct n_tty_data *ldata) static void n_tty_packet_mode_flush(struct tty_struct *tty) { - unsigned long flags; - if (tty->link->ctrl.packet) { - spin_lock_irqsave(&tty->ctrl.lock, flags); - tty->ctrl.pktstatus |= TIOCPKT_FLUSHREAD; - spin_unlock_irqrestore(&tty->ctrl.lock, flags); + scoped_guard(spinlock_irqsave, &tty->ctrl.lock) + tty->ctrl.pktstatus |= TIOCPKT_FLUSHREAD; wake_up_interruptible(&tty->link->read_wait); } } @@ -349,13 +346,12 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty) */ static void n_tty_flush_buffer(struct tty_struct *tty) { - down_write(&tty->termios_rwsem); + guard(rwsem_write)(&tty->termios_rwsem); reset_buffer_flags(tty->disc_data); n_tty_kick_worker(tty); if (tty->link) n_tty_packet_mode_flush(tty); - up_write(&tty->termios_rwsem); } /** @@ -737,24 +733,22 @@ static void commit_echoes(struct tty_struct *tty) size_t nr, old, echoed; size_t head; - mutex_lock(&ldata->output_lock); - head = ldata->echo_head; - ldata->echo_mark = head; - old = ldata->echo_commit - ldata->echo_tail; - - /* Process committed echoes if the accumulated # of bytes - * is over the threshold (and try again each time another - * block is accumulated) */ - nr = head - ldata->echo_tail; - if (nr < ECHO_COMMIT_WATERMARK || - (nr % ECHO_BLOCK > old % ECHO_BLOCK)) { - mutex_unlock(&ldata->output_lock); - return; - } + scoped_guard(mutex, &ldata->output_lock) { + head = ldata->echo_head; + ldata->echo_mark = head; + old = ldata->echo_commit - ldata->echo_tail; + + /* + * Process committed echoes if the accumulated # of bytes is over the threshold + * (and try again each time another block is accumulated) + */ + nr = head - ldata->echo_tail; + if (nr < ECHO_COMMIT_WATERMARK || (nr % ECHO_BLOCK > old % ECHO_BLOCK)) + return; - ldata->echo_commit = head; - echoed = __process_echoes(tty); - mutex_unlock(&ldata->output_lock); + ldata->echo_commit = head; + echoed = __process_echoes(tty); + } if (echoed && tty->ops->flush_chars) tty->ops->flush_chars(tty); @@ -768,10 +762,10 @@ static void process_echoes(struct tty_struct *tty) if (ldata->echo_mark == ldata->echo_tail) return; - mutex_lock(&ldata->output_lock); - ldata->echo_commit = ldata->echo_mark; - echoed = __process_echoes(tty); - mutex_unlock(&ldata->output_lock); + scoped_guard(mutex, &ldata->output_lock) { + ldata->echo_commit = ldata->echo_mark; + echoed = __process_echoes(tty); + } if (echoed && tty->ops->flush_chars) tty->ops->flush_chars(tty); @@ -786,10 +780,9 @@ static void flush_echoes(struct tty_struct *tty) ldata->echo_commit == ldata->echo_head) return; - mutex_lock(&ldata->output_lock); + guard(mutex)(&ldata->output_lock); ldata->echo_commit = ldata->echo_head; __process_echoes(tty); - mutex_unlock(&ldata->output_lock); } /** @@ -1078,18 +1071,19 @@ static void isig(int sig, struct tty_struct *tty) if (L_NOFLSH(tty)) { /* signal only */ __isig(sig, tty); + return; + } - } else { /* signal and flush */ - up_read(&tty->termios_rwsem); - down_write(&tty->termios_rwsem); - + /* signal and flush */ + up_read(&tty->termios_rwsem); + scoped_guard(rwsem_write, &tty->termios_rwsem) { __isig(sig, tty); /* clear echo buffer */ - mutex_lock(&ldata->output_lock); - ldata->echo_head = ldata->echo_tail = 0; - ldata->echo_mark = ldata->echo_commit = 0; - mutex_unlock(&ldata->output_lock); + scoped_guard(mutex, &ldata->output_lock) { + ldata->echo_head = ldata->echo_tail = 0; + ldata->echo_mark = ldata->echo_commit = 0; + } /* clear output buffer */ tty_driver_flush_buffer(tty); @@ -1100,10 +1094,8 @@ static void isig(int sig, struct tty_struct *tty) /* notify pty master of flush */ if (tty->link) n_tty_packet_mode_flush(tty); - - up_write(&tty->termios_rwsem); - down_read(&tty->termios_rwsem); } + down_read(&tty->termios_rwsem); } /** @@ -1683,7 +1675,7 @@ n_tty_receive_buf_common(struct tty_struct *tty, const u8 *cp, const u8 *fp, size_t n, rcvd = 0; int room, overflow; - down_read(&tty->termios_rwsem); + guard(rwsem_read)(&tty->termios_rwsem); do { /* @@ -1752,8 +1744,6 @@ n_tty_receive_buf_common(struct tty_struct *tty, const u8 *cp, const u8 *fp, n_tty_kick_worker(tty); } - up_read(&tty->termios_rwsem); - return rcvd; } @@ -1879,10 +1869,9 @@ static void n_tty_close(struct tty_struct *tty) if (tty->link) n_tty_packet_mode_flush(tty); - down_write(&tty->termios_rwsem); + guard(rwsem_write)(&tty->termios_rwsem); vfree(ldata); tty->disc_data = NULL; - up_write(&tty->termios_rwsem); } /** @@ -2247,10 +2236,10 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, u8 *kbuf, u8 cs; if (kb != kbuf) break; - spin_lock_irq(&tty->link->ctrl.lock); - cs = tty->link->ctrl.pktstatus; - tty->link->ctrl.pktstatus = 0; - spin_unlock_irq(&tty->link->ctrl.lock); + scoped_guard(spinlock_irq, &tty->link->ctrl.lock) { + cs = tty->link->ctrl.pktstatus; + tty->link->ctrl.pktstatus = 0; + } *kb++ = cs; nr--; break; @@ -2357,7 +2346,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, return retval; } - down_read(&tty->termios_rwsem); + guard(rwsem_read)(&tty->termios_rwsem); /* Write out any echoed characters that are still pending */ process_echoes(tty); @@ -2395,9 +2384,8 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, struct n_tty_data *ldata = tty->disc_data; while (nr > 0) { - mutex_lock(&ldata->output_lock); - num = tty->ops->write(tty, b, nr); - mutex_unlock(&ldata->output_lock); + scoped_guard(mutex, &ldata->output_lock) + num = tty->ops->write(tty, b, nr); if (num < 0) { retval = num; goto break_out; @@ -2424,7 +2412,7 @@ break_out: remove_wait_queue(&tty->write_wait, &wait); if (nr && tty->fasync) set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); - up_read(&tty->termios_rwsem); + return (b - buf) ? b - buf : retval; } @@ -2498,12 +2486,11 @@ static int n_tty_ioctl(struct tty_struct *tty, unsigned int cmd, case TIOCOUTQ: return put_user(tty_chars_in_buffer(tty), (int __user *) arg); case TIOCINQ: - down_write(&tty->termios_rwsem); - if (L_ICANON(tty) && !L_EXTPROC(tty)) - num = inq_canon(ldata); - else - num = read_cnt(ldata); - up_write(&tty->termios_rwsem); + scoped_guard(rwsem_write, &tty->termios_rwsem) + if (L_ICANON(tty) && !L_EXTPROC(tty)) + num = inq_canon(ldata); + else + num = read_cnt(ldata); return put_user(num, (unsigned int __user *) arg); default: return n_tty_ioctl_helper(tty, cmd, arg); |
