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/mxser.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/mxser.c')
-rw-r--r-- | drivers/char/mxser.c | 56 |
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) | |||
1080 | static void mxser_close(struct tty_struct *tty, struct file *filp) | 1080 | static 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 | ||
1174 | static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) | 1136 | static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) |