diff options
author | Alan Cox <alan@redhat.com> | 2009-01-02 08:46:50 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-02 13:19:40 -0500 |
commit | a6614999e800cf3a134ce93ea46ef837e3c0e76e (patch) | |
tree | 56b0a29ed004a284561a4c3ff3ee52075acabb65 /drivers/char/synclinkmp.c | |
parent | 7834909f1eb96ba7c49ca2b9e3a69b500a2cff76 (diff) |
tty: Introduce some close helpers for ports
Again this is a lot of common code we can unify
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/synclinkmp.c')
-rw-r--r-- | drivers/char/synclinkmp.c | 58 |
1 files changed, 3 insertions, 55 deletions
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 1f5c21ec4b14..2aac55bcf5fd 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -810,70 +810,18 @@ static void close(struct tty_struct *tty, struct file *filp) | |||
810 | printk("%s(%d):%s close() entry, count=%d\n", | 810 | printk("%s(%d):%s close() entry, count=%d\n", |
811 | __FILE__,__LINE__, info->device_name, info->port.count); | 811 | __FILE__,__LINE__, info->device_name, info->port.count); |
812 | 812 | ||
813 | if (!info->port.count) | 813 | if (tty_port_close_start(&info->port, tty, filp) == 0) |
814 | return; | ||
815 | |||
816 | if (tty_hung_up_p(filp)) | ||
817 | goto cleanup; | ||
818 | |||
819 | if ((tty->count == 1) && (info->port.count != 1)) { | ||
820 | /* | ||
821 | * tty->count is 1 and the tty structure will be freed. | ||
822 | * info->port.count should be one in this case. | ||
823 | * if it's not, correct it so that the port is shutdown. | ||
824 | */ | ||
825 | printk("%s(%d):%s close: bad refcount; tty->count is 1, " | ||
826 | "info->port.count is %d\n", | ||
827 | __FILE__,__LINE__, info->device_name, info->port.count); | ||
828 | info->port.count = 1; | ||
829 | } | ||
830 | |||
831 | info->port.count--; | ||
832 | |||
833 | /* if at least one open remaining, leave hardware active */ | ||
834 | if (info->port.count) | ||
835 | goto cleanup; | 814 | goto cleanup; |
836 | 815 | ||
837 | info->port.flags |= ASYNC_CLOSING; | ||
838 | |||
839 | /* set tty->closing to notify line discipline to | ||
840 | * only process XON/XOFF characters. Only the N_TTY | ||
841 | * discipline appears to use this (ppp does not). | ||
842 | */ | ||
843 | tty->closing = 1; | ||
844 | |||
845 | /* wait for transmit data to clear all layers */ | ||
846 | |||
847 | if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) { | ||
848 | if (debug_level >= DEBUG_LEVEL_INFO) | ||
849 | printk("%s(%d):%s close() calling tty_wait_until_sent\n", | ||
850 | __FILE__,__LINE__, info->device_name ); | ||
851 | tty_wait_until_sent(tty, info->port.closing_wait); | ||
852 | } | ||
853 | |||
854 | if (info->port.flags & ASYNC_INITIALIZED) | 816 | if (info->port.flags & ASYNC_INITIALIZED) |
855 | wait_until_sent(tty, info->timeout); | 817 | wait_until_sent(tty, info->timeout); |
856 | 818 | ||
857 | flush_buffer(tty); | 819 | flush_buffer(tty); |
858 | |||
859 | tty_ldisc_flush(tty); | 820 | tty_ldisc_flush(tty); |
860 | |||
861 | shutdown(info); | 821 | shutdown(info); |
862 | 822 | ||
863 | tty->closing = 0; | 823 | tty_port_close_end(&info->port, tty); |
864 | info->port.tty = NULL; | 824 | info->port.tty = NULL; |
865 | |||
866 | if (info->port.blocked_open) { | ||
867 | if (info->port.close_delay) { | ||
868 | msleep_interruptible(jiffies_to_msecs(info->port.close_delay)); | ||
869 | } | ||
870 | wake_up_interruptible(&info->port.open_wait); | ||
871 | } | ||
872 | |||
873 | info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | ||
874 | |||
875 | wake_up_interruptible(&info->port.close_wait); | ||
876 | |||
877 | cleanup: | 825 | cleanup: |
878 | if (debug_level >= DEBUG_LEVEL_INFO) | 826 | if (debug_level >= DEBUG_LEVEL_INFO) |
879 | printk("%s(%d):%s close() exit, count=%d\n", __FILE__,__LINE__, | 827 | printk("%s(%d):%s close() exit, count=%d\n", __FILE__,__LINE__, |