aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/mxser.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/mxser.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/mxser.c')
-rw-r--r--drivers/char/mxser.c56
1 files changed, 9 insertions, 47 deletions
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 08ba6eb1a380..402c9f217f83 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -1080,58 +1080,27 @@ static void mxser_flush_buffer(struct tty_struct *tty)
1080static void mxser_close(struct tty_struct *tty, struct file *filp) 1080static void mxser_close(struct tty_struct *tty, struct file *filp)
1081{ 1081{
1082 struct mxser_port *info = tty->driver_data; 1082 struct mxser_port *info = tty->driver_data;
1083 struct tty_port *port = &info->port;
1083 1084
1084 unsigned long timeout; 1085 unsigned long timeout;
1085 unsigned long flags;
1086 1086
1087 if (tty->index == MXSER_PORTS) 1087 if (tty->index == MXSER_PORTS)
1088 return; 1088 return;
1089 if (!info) 1089 if (!info)
1090 return; 1090 return;
1091 1091
1092 spin_lock_irqsave(&info->port.lock, flags); 1092 if (tty_port_close_start(port, tty, filp) == 0)
1093
1094 if (tty_hung_up_p(filp)) {
1095 spin_unlock_irqrestore(&info->port.lock, flags);
1096 return;
1097 }
1098 if ((tty->count == 1) && (info->port.count != 1)) {
1099 /*
1100 * Uh, oh. tty->count is 1, which means that the tty
1101 * structure will be freed. Info->port.count should always
1102 * be one in these conditions. If it's greater than
1103 * one, we've got real problems, since it means the
1104 * serial port won't be shutdown.
1105 */
1106 printk(KERN_ERR "mxser_close: bad serial port count; "
1107 "tty->count is 1, info->port.count is %d\n", info->port.count);
1108 info->port.count = 1;
1109 }
1110 if (--info->port.count < 0) {
1111 printk(KERN_ERR "mxser_close: bad serial port count for "
1112 "ttys%d: %d\n", tty->index, info->port.count);
1113 info->port.count = 0;
1114 }
1115 if (info->port.count) {
1116 spin_unlock_irqrestore(&info->port.lock, flags);
1117 return; 1093 return;
1118 } 1094
1119 info->port.flags |= ASYNC_CLOSING;
1120 spin_unlock_irqrestore(&info->port.lock, flags);
1121 /* 1095 /*
1122 * Save the termios structure, since this port may have 1096 * Save the termios structure, since this port may have
1123 * separate termios for callout and dialin. 1097 * separate termios for callout and dialin.
1098 *
1099 * FIXME: Can this go ?
1124 */ 1100 */
1125 if (info->port.flags & ASYNC_NORMAL_ACTIVE) 1101 if (info->port.flags & ASYNC_NORMAL_ACTIVE)
1126 info->normal_termios = *tty->termios; 1102 info->normal_termios = *tty->termios;
1127 /* 1103 /*
1128 * Now we wait for the transmit buffer to clear; and we notify
1129 * the line discipline to only process XON/XOFF characters.
1130 */
1131 tty->closing = 1;
1132 if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1133 tty_wait_until_sent(tty, info->port.closing_wait);
1134 /*
1135 * At this point we stop accepting input. To do this, we 1104 * At this point we stop accepting input. To do this, we
1136 * disable the receive line status interrupts, and tell the 1105 * disable the receive line status interrupts, and tell the
1137 * interrupt driver to stop checking the data ready bit in the 1106 * interrupt driver to stop checking the data ready bit in the
@@ -1156,19 +1125,12 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1156 } 1125 }
1157 } 1126 }
1158 mxser_shutdown(tty); 1127 mxser_shutdown(tty);
1159
1160 mxser_flush_buffer(tty); 1128 mxser_flush_buffer(tty);
1161 tty_ldisc_flush(tty);
1162
1163 tty->closing = 0;
1164 tty_port_tty_set(&info->port, NULL);
1165 if (info->port.blocked_open) {
1166 if (info->port.close_delay)
1167 schedule_timeout_interruptible(info->port.close_delay);
1168 wake_up_interruptible(&info->port.open_wait);
1169 }
1170 1129
1171 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); 1130 /* Right now the tty_port set is done outside of the close_end helper
1131 as we don't yet have everyone using refcounts */
1132 tty_port_close_end(port, tty);
1133 tty_port_tty_set(port, NULL);
1172} 1134}
1173 1135
1174static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) 1136static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)