diff options
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r-- | drivers/char/tty_io.c | 64 |
1 files changed, 8 insertions, 56 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index be49d0730bb9..2f44b0b241c3 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -492,22 +492,6 @@ void tty_ldisc_flush(struct tty_struct *tty) | |||
492 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); | 492 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); |
493 | 493 | ||
494 | /** | 494 | /** |
495 | * tty_reset_termios - reset terminal state | ||
496 | * @tty: tty to reset | ||
497 | * | ||
498 | * Restore a terminal to the driver default state | ||
499 | */ | ||
500 | |||
501 | static void tty_reset_termios(struct tty_struct *tty) | ||
502 | { | ||
503 | mutex_lock(&tty->termios_mutex); | ||
504 | *tty->termios = tty->driver->init_termios; | ||
505 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
506 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
507 | mutex_unlock(&tty->termios_mutex); | ||
508 | } | ||
509 | |||
510 | /** | ||
511 | * do_tty_hangup - actual handler for hangup events | 495 | * do_tty_hangup - actual handler for hangup events |
512 | * @work: tty device | 496 | * @work: tty device |
513 | * | 497 | * |
@@ -536,7 +520,6 @@ static void do_tty_hangup(struct work_struct *work) | |||
536 | struct file *cons_filp = NULL; | 520 | struct file *cons_filp = NULL; |
537 | struct file *filp, *f = NULL; | 521 | struct file *filp, *f = NULL; |
538 | struct task_struct *p; | 522 | struct task_struct *p; |
539 | struct tty_ldisc *ld; | ||
540 | int closecount = 0, n; | 523 | int closecount = 0, n; |
541 | unsigned long flags; | 524 | unsigned long flags; |
542 | int refs = 0; | 525 | int refs = 0; |
@@ -567,40 +550,8 @@ static void do_tty_hangup(struct work_struct *work) | |||
567 | filp->f_op = &hung_up_tty_fops; | 550 | filp->f_op = &hung_up_tty_fops; |
568 | } | 551 | } |
569 | file_list_unlock(); | 552 | file_list_unlock(); |
570 | /* | ||
571 | * FIXME! What are the locking issues here? This may me overdoing | ||
572 | * things... This question is especially important now that we've | ||
573 | * removed the irqlock. | ||
574 | */ | ||
575 | ld = tty_ldisc_ref(tty); | ||
576 | if (ld != NULL) { | ||
577 | /* We may have no line discipline at this point */ | ||
578 | if (ld->ops->flush_buffer) | ||
579 | ld->ops->flush_buffer(tty); | ||
580 | tty_driver_flush_buffer(tty); | ||
581 | if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && | ||
582 | ld->ops->write_wakeup) | ||
583 | ld->ops->write_wakeup(tty); | ||
584 | if (ld->ops->hangup) | ||
585 | ld->ops->hangup(tty); | ||
586 | } | ||
587 | /* | ||
588 | * FIXME: Once we trust the LDISC code better we can wait here for | ||
589 | * ldisc completion and fix the driver call race | ||
590 | */ | ||
591 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); | ||
592 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); | ||
593 | /* | ||
594 | * Shutdown the current line discipline, and reset it to | ||
595 | * N_TTY. | ||
596 | */ | ||
597 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) | ||
598 | tty_reset_termios(tty); | ||
599 | /* Defer ldisc switch */ | ||
600 | /* tty_deferred_ldisc_switch(N_TTY); | ||
601 | 553 | ||
602 | This should get done automatically when the port closes and | 554 | tty_ldisc_hangup(tty); |
603 | tty_release is called */ | ||
604 | 555 | ||
605 | read_lock(&tasklist_lock); | 556 | read_lock(&tasklist_lock); |
606 | if (tty->session) { | 557 | if (tty->session) { |
@@ -629,12 +580,15 @@ static void do_tty_hangup(struct work_struct *work) | |||
629 | read_unlock(&tasklist_lock); | 580 | read_unlock(&tasklist_lock); |
630 | 581 | ||
631 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 582 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
632 | tty->flags = 0; | 583 | clear_bit(TTY_THROTTLED, &tty->flags); |
584 | clear_bit(TTY_PUSH, &tty->flags); | ||
585 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | ||
633 | put_pid(tty->session); | 586 | put_pid(tty->session); |
634 | put_pid(tty->pgrp); | 587 | put_pid(tty->pgrp); |
635 | tty->session = NULL; | 588 | tty->session = NULL; |
636 | tty->pgrp = NULL; | 589 | tty->pgrp = NULL; |
637 | tty->ctrl_status = 0; | 590 | tty->ctrl_status = 0; |
591 | set_bit(TTY_HUPPED, &tty->flags); | ||
638 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 592 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
639 | 593 | ||
640 | /* Account for the p->signal references we killed */ | 594 | /* Account for the p->signal references we killed */ |
@@ -660,10 +614,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
660 | * can't yet guarantee all that. | 614 | * can't yet guarantee all that. |
661 | */ | 615 | */ |
662 | set_bit(TTY_HUPPED, &tty->flags); | 616 | set_bit(TTY_HUPPED, &tty->flags); |
663 | if (ld) { | 617 | tty_ldisc_enable(tty); |
664 | tty_ldisc_enable(tty); | ||
665 | tty_ldisc_deref(ld); | ||
666 | } | ||
667 | unlock_kernel(); | 618 | unlock_kernel(); |
668 | if (f) | 619 | if (f) |
669 | fput(f); | 620 | fput(f); |
@@ -2570,7 +2521,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2570 | case TIOCGSID: | 2521 | case TIOCGSID: |
2571 | return tiocgsid(tty, real_tty, p); | 2522 | return tiocgsid(tty, real_tty, p); |
2572 | case TIOCGETD: | 2523 | case TIOCGETD: |
2573 | return put_user(tty->ldisc.ops->num, (int __user *)p); | 2524 | return put_user(tty->ldisc->ops->num, (int __user *)p); |
2574 | case TIOCSETD: | 2525 | case TIOCSETD: |
2575 | return tiocsetd(tty, p); | 2526 | return tiocsetd(tty, p); |
2576 | /* | 2527 | /* |
@@ -2785,6 +2736,7 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2785 | tty->buf.head = tty->buf.tail = NULL; | 2736 | tty->buf.head = tty->buf.tail = NULL; |
2786 | tty_buffer_init(tty); | 2737 | tty_buffer_init(tty); |
2787 | mutex_init(&tty->termios_mutex); | 2738 | mutex_init(&tty->termios_mutex); |
2739 | mutex_init(&tty->ldisc_mutex); | ||
2788 | init_waitqueue_head(&tty->write_wait); | 2740 | init_waitqueue_head(&tty->write_wait); |
2789 | init_waitqueue_head(&tty->read_wait); | 2741 | init_waitqueue_head(&tty->read_wait); |
2790 | INIT_WORK(&tty->hangup_work, do_tty_hangup); | 2742 | INIT_WORK(&tty->hangup_work, do_tty_hangup); |