aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/isicom.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2009-01-02 08:46:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:40 -0500
commita6614999e800cf3a134ce93ea46ef837e3c0e76e (patch)
tree56b0a29ed004a284561a4c3ff3ee52075acabb65 /drivers/char/isicom.c
parent7834909f1eb96ba7c49ca2b9e3a69b500a2cff76 (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.c66
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
946static void isicom_close(struct tty_struct *tty, struct file *filp) 946static 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 */