aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/mxser.c4
-rw-r--r--drivers/tty/n_gsm.c4
-rw-r--r--drivers/tty/tty_port.c27
3 files changed, 23 insertions, 12 deletions
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index 484b6a3c9b03..d996038eacfd 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -1084,6 +1084,10 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1084 mutex_lock(&port->mutex); 1084 mutex_lock(&port->mutex);
1085 mxser_close_port(port); 1085 mxser_close_port(port);
1086 mxser_flush_buffer(tty); 1086 mxser_flush_buffer(tty);
1087 if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
1088 if (C_HUPCL(tty))
1089 tty_port_lower_dtr_rts(port);
1090 }
1087 mxser_shutdown_port(port); 1091 mxser_shutdown_port(port);
1088 clear_bit(ASYNCB_INITIALIZED, &port->flags); 1092 clear_bit(ASYNCB_INITIALIZED, &port->flags);
1089 mutex_unlock(&port->mutex); 1093 mutex_unlock(&port->mutex);
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 74d9a0258d7c..642239015b46 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -2964,6 +2964,10 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp)
2964 if (tty_port_close_start(&dlci->port, tty, filp) == 0) 2964 if (tty_port_close_start(&dlci->port, tty, filp) == 0)
2965 goto out; 2965 goto out;
2966 gsm_dlci_begin_close(dlci); 2966 gsm_dlci_begin_close(dlci);
2967 if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) {
2968 if (C_HUPCL(tty))
2969 tty_port_lower_dtr_rts(&dlci->port);
2970 }
2967 tty_port_close_end(&dlci->port, tty); 2971 tty_port_close_end(&dlci->port, tty);
2968 tty_port_tty_set(&dlci->port, NULL); 2972 tty_port_tty_set(&dlci->port, NULL);
2969out: 2973out:
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index 7e3eaf4eb9fe..0af8d9aa5b02 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -196,13 +196,20 @@ void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
196} 196}
197EXPORT_SYMBOL(tty_port_tty_set); 197EXPORT_SYMBOL(tty_port_tty_set);
198 198
199static void tty_port_shutdown(struct tty_port *port) 199static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
200{ 200{
201 mutex_lock(&port->mutex); 201 mutex_lock(&port->mutex);
202 if (port->console) 202 if (port->console)
203 goto out; 203 goto out;
204 204
205 if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) { 205 if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) {
206 /*
207 * Drop DTR/RTS if HUPCL is set. This causes any attached
208 * modem to hang up the line.
209 */
210 if (tty && C_HUPCL(tty))
211 tty_port_lower_dtr_rts(port);
212
206 if (port->ops->shutdown) 213 if (port->ops->shutdown)
207 port->ops->shutdown(port); 214 port->ops->shutdown(port);
208 } 215 }
@@ -220,18 +227,19 @@ out:
220 227
221void tty_port_hangup(struct tty_port *port) 228void tty_port_hangup(struct tty_port *port)
222{ 229{
230 struct tty_struct *tty;
223 unsigned long flags; 231 unsigned long flags;
224 232
225 spin_lock_irqsave(&port->lock, flags); 233 spin_lock_irqsave(&port->lock, flags);
226 port->count = 0; 234 port->count = 0;
227 port->flags &= ~ASYNC_NORMAL_ACTIVE; 235 port->flags &= ~ASYNC_NORMAL_ACTIVE;
228 if (port->tty) { 236 tty = port->tty;
229 set_bit(TTY_IO_ERROR, &port->tty->flags); 237 if (tty)
230 tty_kref_put(port->tty); 238 set_bit(TTY_IO_ERROR, &tty->flags);
231 }
232 port->tty = NULL; 239 port->tty = NULL;
233 spin_unlock_irqrestore(&port->lock, flags); 240 spin_unlock_irqrestore(&port->lock, flags);
234 tty_port_shutdown(port); 241 tty_port_shutdown(port, tty);
242 tty_kref_put(tty);
235 wake_up_interruptible(&port->open_wait); 243 wake_up_interruptible(&port->open_wait);
236 wake_up_interruptible(&port->delta_msr_wait); 244 wake_up_interruptible(&port->delta_msr_wait);
237} 245}
@@ -485,11 +493,6 @@ int tty_port_close_start(struct tty_port *port,
485 /* Flush the ldisc buffering */ 493 /* Flush the ldisc buffering */
486 tty_ldisc_flush(tty); 494 tty_ldisc_flush(tty);
487 495
488 /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
489 hang up the line */
490 if (tty->termios.c_cflag & HUPCL)
491 tty_port_lower_dtr_rts(port);
492
493 /* Don't call port->drop for the last reference. Callers will want 496 /* Don't call port->drop for the last reference. Callers will want
494 to drop the last active reference in ->shutdown() or the tty 497 to drop the last active reference in ->shutdown() or the tty
495 shutdown path */ 498 shutdown path */
@@ -524,7 +527,7 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty,
524{ 527{
525 if (tty_port_close_start(port, tty, filp) == 0) 528 if (tty_port_close_start(port, tty, filp) == 0)
526 return; 529 return;
527 tty_port_shutdown(port); 530 tty_port_shutdown(port, tty);
528 set_bit(TTY_IO_ERROR, &tty->flags); 531 set_bit(TTY_IO_ERROR, &tty->flags);
529 tty_port_close_end(port, tty); 532 tty_port_close_end(port, tty);
530 tty_port_tty_set(port, NULL); 533 tty_port_tty_set(port, NULL);