Lines Matching refs:tty

27 #define tty_ldisc_debug(tty, f, args...)	tty_debug(tty, f, ##args)  argument
29 #define tty_ldisc_debug(tty, f, args...) argument
139 static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc) in tty_ldisc_get() argument
167 ld->tty = tty; in tty_ldisc_get()
239 struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) in tty_ldisc_ref_wait() argument
243 ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT); in tty_ldisc_ref_wait()
244 ld = tty->ldisc; in tty_ldisc_ref_wait()
246 ldsem_up_read(&tty->ldisc_sem); in tty_ldisc_ref_wait()
259 struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) in tty_ldisc_ref() argument
263 if (ldsem_down_read_trylock(&tty->ldisc_sem)) { in tty_ldisc_ref()
264 ld = tty->ldisc; in tty_ldisc_ref()
266 ldsem_up_read(&tty->ldisc_sem); in tty_ldisc_ref()
281 ldsem_up_read(&ld->tty->ldisc_sem); in tty_ldisc_deref()
287 __tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) in __tty_ldisc_lock() argument
289 return ldsem_down_write(&tty->ldisc_sem, timeout); in __tty_ldisc_lock()
293 __tty_ldisc_lock_nested(struct tty_struct *tty, unsigned long timeout) in __tty_ldisc_lock_nested() argument
295 return ldsem_down_write_nested(&tty->ldisc_sem, in __tty_ldisc_lock_nested()
299 static inline void __tty_ldisc_unlock(struct tty_struct *tty) in __tty_ldisc_unlock() argument
301 ldsem_up_write(&tty->ldisc_sem); in __tty_ldisc_unlock()
304 int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) in tty_ldisc_lock() argument
309 set_bit(TTY_LDISC_CHANGING, &tty->flags); in tty_ldisc_lock()
310 wake_up_interruptible_all(&tty->read_wait); in tty_ldisc_lock()
311 wake_up_interruptible_all(&tty->write_wait); in tty_ldisc_lock()
313 ret = __tty_ldisc_lock(tty, timeout); in tty_ldisc_lock()
316 set_bit(TTY_LDISC_HALTED, &tty->flags); in tty_ldisc_lock()
320 void tty_ldisc_unlock(struct tty_struct *tty) in tty_ldisc_unlock() argument
322 clear_bit(TTY_LDISC_HALTED, &tty->flags); in tty_ldisc_unlock()
324 clear_bit(TTY_LDISC_CHANGING, &tty->flags); in tty_ldisc_unlock()
325 __tty_ldisc_unlock(tty); in tty_ldisc_unlock()
329 tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2, in tty_ldisc_lock_pair_timeout() argument
334 if (tty < tty2) { in tty_ldisc_lock_pair_timeout()
335 ret = __tty_ldisc_lock(tty, timeout); in tty_ldisc_lock_pair_timeout()
339 __tty_ldisc_unlock(tty); in tty_ldisc_lock_pair_timeout()
343 WARN_ON_ONCE(tty == tty2); in tty_ldisc_lock_pair_timeout()
344 if (tty2 && tty != tty2) { in tty_ldisc_lock_pair_timeout()
347 ret = __tty_ldisc_lock_nested(tty, timeout); in tty_ldisc_lock_pair_timeout()
352 ret = __tty_ldisc_lock(tty, timeout); in tty_ldisc_lock_pair_timeout()
358 set_bit(TTY_LDISC_HALTED, &tty->flags); in tty_ldisc_lock_pair_timeout()
364 static void tty_ldisc_lock_pair(struct tty_struct *tty, struct tty_struct *tty2) in tty_ldisc_lock_pair() argument
366 tty_ldisc_lock_pair_timeout(tty, tty2, MAX_SCHEDULE_TIMEOUT); in tty_ldisc_lock_pair()
369 static void tty_ldisc_unlock_pair(struct tty_struct *tty, in tty_ldisc_unlock_pair() argument
372 __tty_ldisc_unlock(tty); in tty_ldisc_unlock_pair()
384 void tty_ldisc_flush(struct tty_struct *tty) in tty_ldisc_flush() argument
386 struct tty_ldisc *ld = tty_ldisc_ref(tty); in tty_ldisc_flush()
388 tty_buffer_flush(tty, ld); in tty_ldisc_flush()
407 static void tty_set_termios_ldisc(struct tty_struct *tty, int disc) in tty_set_termios_ldisc() argument
409 down_write(&tty->termios_rwsem); in tty_set_termios_ldisc()
410 tty->termios.c_line = disc; in tty_set_termios_ldisc()
411 up_write(&tty->termios_rwsem); in tty_set_termios_ldisc()
413 tty->disc_data = NULL; in tty_set_termios_ldisc()
414 tty->receive_room = 0; in tty_set_termios_ldisc()
426 static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) in tty_ldisc_open() argument
428 WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags)); in tty_ldisc_open()
432 ret = ld->ops->open(tty); in tty_ldisc_open()
434 clear_bit(TTY_LDISC_OPEN, &tty->flags); in tty_ldisc_open()
436 tty_ldisc_debug(tty, "%p: opened\n", ld); in tty_ldisc_open()
449 static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld) in tty_ldisc_close() argument
451 lockdep_assert_held_write(&tty->ldisc_sem); in tty_ldisc_close()
452 WARN_ON(!test_bit(TTY_LDISC_OPEN, &tty->flags)); in tty_ldisc_close()
453 clear_bit(TTY_LDISC_OPEN, &tty->flags); in tty_ldisc_close()
455 ld->ops->close(tty); in tty_ldisc_close()
456 tty_ldisc_debug(tty, "%p: closed\n", ld); in tty_ldisc_close()
467 static int tty_ldisc_failto(struct tty_struct *tty, int ld) in tty_ldisc_failto() argument
469 struct tty_ldisc *disc = tty_ldisc_get(tty, ld); in tty_ldisc_failto()
472 lockdep_assert_held_write(&tty->ldisc_sem); in tty_ldisc_failto()
475 tty->ldisc = disc; in tty_ldisc_failto()
476 tty_set_termios_ldisc(tty, ld); in tty_ldisc_failto()
477 r = tty_ldisc_open(tty, disc); in tty_ldisc_failto()
491 static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) in tty_ldisc_restore() argument
494 if (tty_ldisc_failto(tty, old->ops->num) < 0) { in tty_ldisc_restore()
495 const char *name = tty_name(tty); in tty_ldisc_restore()
503 if (tty_ldisc_failto(tty, N_TTY) < 0 && in tty_ldisc_restore()
504 tty_ldisc_failto(tty, N_NULL) < 0) in tty_ldisc_restore()
519 int tty_set_ldisc(struct tty_struct *tty, int disc) in tty_set_ldisc() argument
524 new_ldisc = tty_ldisc_get(tty, disc); in tty_set_ldisc()
528 tty_lock(tty); in tty_set_ldisc()
529 retval = tty_ldisc_lock(tty, 5 * HZ); in tty_set_ldisc()
533 if (!tty->ldisc) { in tty_set_ldisc()
539 if (tty->ldisc->ops->num == disc) in tty_set_ldisc()
542 if (test_bit(TTY_HUPPED, &tty->flags)) { in tty_set_ldisc()
548 if (tty->ops->ldisc_ok) { in tty_set_ldisc()
549 retval = tty->ops->ldisc_ok(tty, disc); in tty_set_ldisc()
554 old_ldisc = tty->ldisc; in tty_set_ldisc()
557 tty_ldisc_close(tty, old_ldisc); in tty_set_ldisc()
560 tty->ldisc = new_ldisc; in tty_set_ldisc()
561 tty_set_termios_ldisc(tty, disc); in tty_set_ldisc()
563 retval = tty_ldisc_open(tty, new_ldisc); in tty_set_ldisc()
567 tty_ldisc_restore(tty, old_ldisc); in tty_set_ldisc()
570 if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) { in tty_set_ldisc()
571 down_read(&tty->termios_rwsem); in tty_set_ldisc()
572 tty->ops->set_ldisc(tty); in tty_set_ldisc()
573 up_read(&tty->termios_rwsem); in tty_set_ldisc()
585 tty_ldisc_unlock(tty); in tty_set_ldisc()
591 tty_buffer_restart_work(tty->port); in tty_set_ldisc()
594 tty_unlock(tty); in tty_set_ldisc()
605 static void tty_ldisc_kill(struct tty_struct *tty) in tty_ldisc_kill() argument
607 lockdep_assert_held_write(&tty->ldisc_sem); in tty_ldisc_kill()
608 if (!tty->ldisc) in tty_ldisc_kill()
613 tty_ldisc_close(tty, tty->ldisc); in tty_ldisc_kill()
614 tty_ldisc_put(tty->ldisc); in tty_ldisc_kill()
616 tty->ldisc = NULL; in tty_ldisc_kill()
625 static void tty_reset_termios(struct tty_struct *tty) in tty_reset_termios() argument
627 down_write(&tty->termios_rwsem); in tty_reset_termios()
628 tty->termios = tty->driver->init_termios; in tty_reset_termios()
629 tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios); in tty_reset_termios()
630 tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); in tty_reset_termios()
631 up_write(&tty->termios_rwsem); in tty_reset_termios()
647 int tty_ldisc_reinit(struct tty_struct *tty, int disc) in tty_ldisc_reinit() argument
652 lockdep_assert_held_write(&tty->ldisc_sem); in tty_ldisc_reinit()
653 ld = tty_ldisc_get(tty, disc); in tty_ldisc_reinit()
659 if (tty->ldisc) { in tty_ldisc_reinit()
660 tty_ldisc_close(tty, tty->ldisc); in tty_ldisc_reinit()
661 tty_ldisc_put(tty->ldisc); in tty_ldisc_reinit()
665 tty->ldisc = ld; in tty_ldisc_reinit()
666 tty_set_termios_ldisc(tty, disc); in tty_ldisc_reinit()
667 retval = tty_ldisc_open(tty, tty->ldisc); in tty_ldisc_reinit()
669 tty_ldisc_put(tty->ldisc); in tty_ldisc_reinit()
670 tty->ldisc = NULL; in tty_ldisc_reinit()
690 void tty_ldisc_hangup(struct tty_struct *tty, bool reinit) in tty_ldisc_hangup() argument
694 tty_ldisc_debug(tty, "%p: hangup\n", tty->ldisc); in tty_ldisc_hangup()
696 ld = tty_ldisc_ref(tty); in tty_ldisc_hangup()
699 ld->ops->flush_buffer(tty); in tty_ldisc_hangup()
700 tty_driver_flush_buffer(tty); in tty_ldisc_hangup()
701 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && in tty_ldisc_hangup()
703 ld->ops->write_wakeup(tty); in tty_ldisc_hangup()
705 ld->ops->hangup(tty); in tty_ldisc_hangup()
709 wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT); in tty_ldisc_hangup()
710 wake_up_interruptible_poll(&tty->read_wait, EPOLLIN); in tty_ldisc_hangup()
718 tty_ldisc_lock(tty, MAX_SCHEDULE_TIMEOUT); in tty_ldisc_hangup()
720 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) in tty_ldisc_hangup()
721 tty_reset_termios(tty); in tty_ldisc_hangup()
723 if (tty->ldisc) { in tty_ldisc_hangup()
725 if (tty_ldisc_reinit(tty, tty->termios.c_line) < 0 && in tty_ldisc_hangup()
726 tty_ldisc_reinit(tty, N_TTY) < 0) in tty_ldisc_hangup()
727 WARN_ON(tty_ldisc_reinit(tty, N_NULL) < 0); in tty_ldisc_hangup()
729 tty_ldisc_kill(tty); in tty_ldisc_hangup()
731 tty_ldisc_unlock(tty); in tty_ldisc_hangup()
743 int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) in tty_ldisc_setup() argument
745 int retval = tty_ldisc_open(tty, tty->ldisc); in tty_ldisc_setup()
757 tty_ldisc_close(tty, tty->ldisc); in tty_ldisc_setup()
771 void tty_ldisc_release(struct tty_struct *tty) in tty_ldisc_release() argument
773 struct tty_struct *o_tty = tty->link; in tty_ldisc_release()
780 tty_ldisc_lock_pair(tty, o_tty); in tty_ldisc_release()
781 tty_ldisc_kill(tty); in tty_ldisc_release()
784 tty_ldisc_unlock_pair(tty, o_tty); in tty_ldisc_release()
791 tty_ldisc_debug(tty, "released\n"); in tty_ldisc_release()
801 int tty_ldisc_init(struct tty_struct *tty) in tty_ldisc_init() argument
803 struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY); in tty_ldisc_init()
807 tty->ldisc = ld; in tty_ldisc_init()
818 void tty_ldisc_deinit(struct tty_struct *tty) in tty_ldisc_deinit() argument
821 if (tty->ldisc) in tty_ldisc_deinit()
822 tty_ldisc_put(tty->ldisc); in tty_ldisc_deinit()
823 tty->ldisc = NULL; in tty_ldisc_deinit()