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/isicom.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/isicom.c')
-rw-r--r-- | drivers/char/isicom.c | 66 |
1 files changed, 10 insertions, 56 deletions
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index bac55cf44243..24aa6e88e223 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -945,76 +945,30 @@ static void isicom_flush_buffer(struct tty_struct *tty) | |||
945 | 945 | ||
946 | static void isicom_close(struct tty_struct *tty, struct file *filp) | 946 | static void isicom_close(struct tty_struct *tty, struct file *filp) |
947 | { | 947 | { |
948 | struct isi_port *port = tty->driver_data; | 948 | struct isi_port *ip = tty->driver_data; |
949 | struct tty_port *port = &ip->port; | ||
949 | struct isi_board *card; | 950 | struct isi_board *card; |
950 | unsigned long flags; | 951 | unsigned long flags; |
951 | 952 | ||
952 | if (!port) | 953 | BUG_ON(!ip); |
953 | return; | ||
954 | card = port->card; | ||
955 | if (isicom_paranoia_check(port, tty->name, "isicom_close")) | ||
956 | return; | ||
957 | |||
958 | pr_dbg("Close start!!!.\n"); | ||
959 | |||
960 | spin_lock_irqsave(&port->port.lock, flags); | ||
961 | if (tty_hung_up_p(filp)) { | ||
962 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
963 | return; | ||
964 | } | ||
965 | |||
966 | if (tty->count == 1 && port->port.count != 1) { | ||
967 | printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port " | ||
968 | "count tty->count = 1 port count = %d.\n", | ||
969 | card->base, port->port.count); | ||
970 | port->port.count = 1; | ||
971 | } | ||
972 | if (--port->port.count < 0) { | ||
973 | printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port " | ||
974 | "count for channel%d = %d", card->base, port->channel, | ||
975 | port->port.count); | ||
976 | port->port.count = 0; | ||
977 | } | ||
978 | 954 | ||
979 | if (port->port.count) { | 955 | card = ip->card; |
980 | spin_unlock_irqrestore(&port->port.lock, flags); | 956 | if (isicom_paranoia_check(ip, tty->name, "isicom_close")) |
981 | return; | 957 | return; |
982 | } | ||
983 | port->port.flags |= ASYNC_CLOSING; | ||
984 | tty->closing = 1; | ||
985 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
986 | 958 | ||
987 | if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
988 | tty_wait_until_sent(tty, port->port.closing_wait); | ||
989 | /* indicate to the card that no more data can be received | 959 | /* indicate to the card that no more data can be received |
990 | on this port */ | 960 | on this port */ |
991 | spin_lock_irqsave(&card->card_lock, flags); | 961 | spin_lock_irqsave(&card->card_lock, flags); |
992 | if (port->port.flags & ASYNC_INITIALIZED) { | 962 | if (port->flags & ASYNC_INITIALIZED) { |
993 | card->port_status &= ~(1 << port->channel); | 963 | card->port_status &= ~(1 << ip->channel); |
994 | outw(card->port_status, card->base + 0x02); | 964 | outw(card->port_status, card->base + 0x02); |
995 | } | 965 | } |
996 | isicom_shutdown_port(port); | 966 | isicom_shutdown_port(ip); |
997 | spin_unlock_irqrestore(&card->card_lock, flags); | 967 | spin_unlock_irqrestore(&card->card_lock, flags); |
998 | 968 | ||
999 | isicom_flush_buffer(tty); | 969 | isicom_flush_buffer(tty); |
1000 | tty_ldisc_flush(tty); | 970 | |
1001 | 971 | tty_port_close_end(port, tty); | |
1002 | spin_lock_irqsave(&port->port.lock, flags); | ||
1003 | tty->closing = 0; | ||
1004 | |||
1005 | if (port->port.blocked_open) { | ||
1006 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
1007 | if (port->port.close_delay) { | ||
1008 | pr_dbg("scheduling until time out.\n"); | ||
1009 | msleep_interruptible( | ||
1010 | jiffies_to_msecs(port->port.close_delay)); | ||
1011 | } | ||
1012 | spin_lock_irqsave(&port->port.lock, flags); | ||
1013 | wake_up_interruptible(&port->port.open_wait); | ||
1014 | } | ||
1015 | port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | ||
1016 | wake_up_interruptible(&port->port.close_wait); | ||
1017 | spin_unlock_irqrestore(&port->port.lock, flags); | ||
1018 | } | 972 | } |
1019 | 973 | ||
1020 | /* write et all */ | 974 | /* write et all */ |