aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2013-03-07 07:12:30 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-18 19:24:29 -0400
commitaa27a094e2c2e0cc59914e56113b860f524f4479 (patch)
treeb3cfef8d8023741107e3d3bed934f2bd4d8bf189
parente4408ce3c23f8451eff7a2954694598fb8fce833 (diff)
TTY: add tty_port_tty_hangup helper
It allows for cleaning up on a considerable amount of places. They did port_get, hangup, kref_put. Now the only thing needed is to call tty_port_tty_hangup which does exactly that. And they can also decide whether to consider CLOCAL or completely ignore that. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/um/drivers/chan_kern.c6
-rw-r--r--drivers/mmc/card/sdio_uart.c13
-rw-r--r--drivers/net/usb/hso.c7
-rw-r--r--drivers/tty/cyclades.c10
-rw-r--r--drivers/tty/moxa.c19
-rw-r--r--drivers/tty/n_gsm.c6
-rw-r--r--drivers/tty/nozomi.c9
-rw-r--r--drivers/tty/rocket.c7
-rw-r--r--drivers/tty/serial/ifx6x60.c21
-rw-r--r--drivers/tty/tty_port.c17
-rw-r--r--drivers/usb/class/cdc-acm.c24
-rw-r--r--drivers/usb/serial/keyspan.c43
-rw-r--r--drivers/usb/serial/option.c9
-rw-r--r--drivers/usb/serial/sierra.c8
-rw-r--r--include/linux/tty.h1
-rw-r--r--net/irda/ircomm/ircomm_tty_attach.c6
16 files changed, 58 insertions, 148 deletions
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 15c553c239a1..bf42825ba54f 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -568,11 +568,7 @@ void chan_interrupt(struct line *line, int irq)
568 reactivate_fd(chan->fd, irq); 568 reactivate_fd(chan->fd, irq);
569 if (err == -EIO) { 569 if (err == -EIO) {
570 if (chan->primary) { 570 if (chan->primary) {
571 struct tty_struct *tty = tty_port_tty_get(&line->port); 571 tty_port_tty_hangup(&line->port, false);
572 if (tty != NULL) {
573 tty_hangup(tty);
574 tty_kref_put(tty);
575 }
576 if (line->chan_out != chan) 572 if (line->chan_out != chan)
577 close_one_chan(line->chan_out, 1); 573 close_one_chan(line->chan_out, 1);
578 } 574 }
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index c931dfe6a59c..f093cea0d060 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -134,7 +134,6 @@ static void sdio_uart_port_put(struct sdio_uart_port *port)
134static void sdio_uart_port_remove(struct sdio_uart_port *port) 134static void sdio_uart_port_remove(struct sdio_uart_port *port)
135{ 135{
136 struct sdio_func *func; 136 struct sdio_func *func;
137 struct tty_struct *tty;
138 137
139 BUG_ON(sdio_uart_table[port->index] != port); 138 BUG_ON(sdio_uart_table[port->index] != port);
140 139
@@ -155,12 +154,8 @@ static void sdio_uart_port_remove(struct sdio_uart_port *port)
155 sdio_claim_host(func); 154 sdio_claim_host(func);
156 port->func = NULL; 155 port->func = NULL;
157 mutex_unlock(&port->func_lock); 156 mutex_unlock(&port->func_lock);
158 tty = tty_port_tty_get(&port->port);
159 /* tty_hangup is async so is this safe as is ?? */ 157 /* tty_hangup is async so is this safe as is ?? */
160 if (tty) { 158 tty_port_tty_hangup(&port->port, false);
161 tty_hangup(tty);
162 tty_kref_put(tty);
163 }
164 mutex_unlock(&port->port.mutex); 159 mutex_unlock(&port->port.mutex);
165 sdio_release_irq(func); 160 sdio_release_irq(func);
166 sdio_disable_func(func); 161 sdio_disable_func(func);
@@ -492,11 +487,7 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
492 wake_up_interruptible(&port->port.open_wait); 487 wake_up_interruptible(&port->port.open_wait);
493 else { 488 else {
494 /* DCD drop - hang up if tty attached */ 489 /* DCD drop - hang up if tty attached */
495 tty = tty_port_tty_get(&port->port); 490 tty_port_tty_hangup(&port->port, false);
496 if (tty) {
497 tty_hangup(tty);
498 tty_kref_put(tty);
499 }
500 } 491 }
501 } 492 }
502 if (status & UART_MSR_DCTS) { 493 if (status & UART_MSR_DCTS) {
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index a7714b4f29ad..cba1d46e672e 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -3124,18 +3124,13 @@ static void hso_serial_ref_free(struct kref *ref)
3124static void hso_free_interface(struct usb_interface *interface) 3124static void hso_free_interface(struct usb_interface *interface)
3125{ 3125{
3126 struct hso_serial *hso_dev; 3126 struct hso_serial *hso_dev;
3127 struct tty_struct *tty;
3128 int i; 3127 int i;
3129 3128
3130 for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { 3129 for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
3131 if (serial_table[i] && 3130 if (serial_table[i] &&
3132 (serial_table[i]->interface == interface)) { 3131 (serial_table[i]->interface == interface)) {
3133 hso_dev = dev2ser(serial_table[i]); 3132 hso_dev = dev2ser(serial_table[i]);
3134 tty = tty_port_tty_get(&hso_dev->port); 3133 tty_port_tty_hangup(&hso_dev->port, false);
3135 if (tty) {
3136 tty_hangup(tty);
3137 tty_kref_put(tty);
3138 }
3139 mutex_lock(&hso_dev->parent->mutex); 3134 mutex_lock(&hso_dev->parent->mutex);
3140 hso_dev->parent->usb_gone = 1; 3135 hso_dev->parent->usb_gone = 1;
3141 mutex_unlock(&hso_dev->parent->mutex); 3136 mutex_unlock(&hso_dev->parent->mutex);
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c
index 345bd0e0884e..33f83fee9fae 100644
--- a/drivers/tty/cyclades.c
+++ b/drivers/tty/cyclades.c
@@ -1124,14 +1124,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1124 readl(&info->u.cyz.ch_ctrl->rs_status); 1124 readl(&info->u.cyz.ch_ctrl->rs_status);
1125 if (dcd & C_RS_DCD) 1125 if (dcd & C_RS_DCD)
1126 wake_up_interruptible(&info->port.open_wait); 1126 wake_up_interruptible(&info->port.open_wait);
1127 else { 1127 else
1128 struct tty_struct *tty; 1128 tty_port_tty_hangup(&info->port, false);
1129 tty = tty_port_tty_get(&info->port);
1130 if (tty) {
1131 tty_hangup(tty);
1132 tty_kref_put(tty);
1133 }
1134 }
1135 } 1129 }
1136 break; 1130 break;
1137 case C_CM_MCTS: 1131 case C_CM_MCTS:
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c
index adeac255e526..1deaca4674e4 100644
--- a/drivers/tty/moxa.c
+++ b/drivers/tty/moxa.c
@@ -913,16 +913,12 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
913 913
914 /* pci hot-un-plug support */ 914 /* pci hot-un-plug support */
915 for (a = 0; a < brd->numPorts; a++) 915 for (a = 0; a < brd->numPorts; a++)
916 if (brd->ports[a].port.flags & ASYNC_INITIALIZED) { 916 if (brd->ports[a].port.flags & ASYNC_INITIALIZED)
917 struct tty_struct *tty = tty_port_tty_get( 917 tty_port_tty_hangup(&brd->ports[a].port, false);
918 &brd->ports[a].port); 918
919 if (tty) {
920 tty_hangup(tty);
921 tty_kref_put(tty);
922 }
923 }
924 for (a = 0; a < MAX_PORTS_PER_BOARD; a++) 919 for (a = 0; a < MAX_PORTS_PER_BOARD; a++)
925 tty_port_destroy(&brd->ports[a].port); 920 tty_port_destroy(&brd->ports[a].port);
921
926 while (1) { 922 while (1) {
927 opened = 0; 923 opened = 0;
928 for (a = 0; a < brd->numPorts; a++) 924 for (a = 0; a < brd->numPorts; a++)
@@ -1365,7 +1361,6 @@ static void moxa_hangup(struct tty_struct *tty)
1365 1361
1366static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) 1362static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
1367{ 1363{
1368 struct tty_struct *tty;
1369 unsigned long flags; 1364 unsigned long flags;
1370 dcd = !!dcd; 1365 dcd = !!dcd;
1371 1366
@@ -1373,10 +1368,8 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
1373 if (dcd != p->DCDState) { 1368 if (dcd != p->DCDState) {
1374 p->DCDState = dcd; 1369 p->DCDState = dcd;
1375 spin_unlock_irqrestore(&p->port.lock, flags); 1370 spin_unlock_irqrestore(&p->port.lock, flags);
1376 tty = tty_port_tty_get(&p->port); 1371 if (!dcd)
1377 if (tty && !C_CLOCAL(tty) && !dcd) 1372 tty_port_tty_hangup(&p->port, true);
1378 tty_hangup(tty);
1379 tty_kref_put(tty);
1380 } 1373 }
1381 else 1374 else
1382 spin_unlock_irqrestore(&p->port.lock, flags); 1375 spin_unlock_irqrestore(&p->port.lock, flags);
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 4a43ef5d7962..74d9a0258d7c 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -1418,11 +1418,7 @@ static void gsm_dlci_close(struct gsm_dlci *dlci)
1418 pr_debug("DLCI %d goes closed.\n", dlci->addr); 1418 pr_debug("DLCI %d goes closed.\n", dlci->addr);
1419 dlci->state = DLCI_CLOSED; 1419 dlci->state = DLCI_CLOSED;
1420 if (dlci->addr != 0) { 1420 if (dlci->addr != 0) {
1421 struct tty_struct *tty = tty_port_tty_get(&dlci->port); 1421 tty_port_tty_hangup(&dlci->port, false);
1422 if (tty) {
1423 tty_hangup(tty);
1424 tty_kref_put(tty);
1425 }
1426 kfifo_reset(dlci->fifo); 1422 kfifo_reset(dlci->fifo);
1427 } else 1423 } else
1428 dlci->gsm->dead = 1; 1424 dlci->gsm->dead = 1;
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c
index 2e5bbdc09e1c..d6080c3831ef 100644
--- a/drivers/tty/nozomi.c
+++ b/drivers/tty/nozomi.c
@@ -1501,12 +1501,9 @@ static void tty_exit(struct nozomi *dc)
1501 1501
1502 DBG1(" "); 1502 DBG1(" ");
1503 1503
1504 for (i = 0; i < MAX_PORT; ++i) { 1504 for (i = 0; i < MAX_PORT; ++i)
1505 struct tty_struct *tty = tty_port_tty_get(&dc->port[i].port); 1505 tty_port_tty_hangup(&dc->port[i].port, false);
1506 if (tty && list_empty(&tty->hangup_work.entry)) 1506
1507 tty_hangup(tty);
1508 tty_kref_put(tty);
1509 }
1510 /* Racy below - surely should wait for scheduled work to be done or 1507 /* Racy below - surely should wait for scheduled work to be done or
1511 complete off a hangup method ? */ 1508 complete off a hangup method ? */
1512 while (dc->open_ttys) 1509 while (dc->open_ttys)
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c
index 1d270034bfc3..bbffd7a431e9 100644
--- a/drivers/tty/rocket.c
+++ b/drivers/tty/rocket.c
@@ -521,15 +521,10 @@ static void rp_handle_port(struct r_port *info)
521 (ChanStatus & CD_ACT) ? "on" : "off"); 521 (ChanStatus & CD_ACT) ? "on" : "off");
522#endif 522#endif
523 if (!(ChanStatus & CD_ACT) && info->cd_status) { 523 if (!(ChanStatus & CD_ACT) && info->cd_status) {
524 struct tty_struct *tty;
525#ifdef ROCKET_DEBUG_HANGUP 524#ifdef ROCKET_DEBUG_HANGUP
526 printk(KERN_INFO "CD drop, calling hangup.\n"); 525 printk(KERN_INFO "CD drop, calling hangup.\n");
527#endif 526#endif
528 tty = tty_port_tty_get(&info->port); 527 tty_port_tty_hangup(&info->port, false);
529 if (tty) {
530 tty_hangup(tty);
531 tty_kref_put(tty);
532 }
533 } 528 }
534 info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0; 529 info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0;
535 wake_up_interruptible(&info->port.open_wait); 530 wake_up_interruptible(&info->port.open_wait);
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c
index d723d4193b90..2c77fed31a72 100644
--- a/drivers/tty/serial/ifx6x60.c
+++ b/drivers/tty/serial/ifx6x60.c
@@ -270,23 +270,6 @@ static void mrdy_assert(struct ifx_spi_device *ifx_dev)
270} 270}
271 271
272/** 272/**
273 * ifx_spi_hangup - hang up an IFX device
274 * @ifx_dev: our SPI device
275 *
276 * Hang up the tty attached to the IFX device if one is currently
277 * open. If not take no action
278 */
279static void ifx_spi_ttyhangup(struct ifx_spi_device *ifx_dev)
280{
281 struct tty_port *pport = &ifx_dev->tty_port;
282 struct tty_struct *tty = tty_port_tty_get(pport);
283 if (tty) {
284 tty_hangup(tty);
285 tty_kref_put(tty);
286 }
287}
288
289/**
290 * ifx_spi_timeout - SPI timeout 273 * ifx_spi_timeout - SPI timeout
291 * @arg: our SPI device 274 * @arg: our SPI device
292 * 275 *
@@ -298,7 +281,7 @@ static void ifx_spi_timeout(unsigned long arg)
298 struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *)arg; 281 struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *)arg;
299 282
300 dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***"); 283 dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***");
301 ifx_spi_ttyhangup(ifx_dev); 284 tty_port_tty_hangup(&ifx_dev->tty_port, false);
302 mrdy_set_low(ifx_dev); 285 mrdy_set_low(ifx_dev);
303 clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); 286 clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
304} 287}
@@ -933,7 +916,7 @@ static irqreturn_t ifx_spi_reset_interrupt(int irq, void *dev)
933 set_bit(MR_INPROGRESS, &ifx_dev->mdm_reset_state); 916 set_bit(MR_INPROGRESS, &ifx_dev->mdm_reset_state);
934 if (!solreset) { 917 if (!solreset) {
935 /* unsolicited reset */ 918 /* unsolicited reset */
936 ifx_spi_ttyhangup(ifx_dev); 919 tty_port_tty_hangup(&ifx_dev->tty_port, false);
937 } 920 }
938 } else { 921 } else {
939 /* exited reset */ 922 /* exited reset */
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index 8bb757c62ee2..7f38eeaafac3 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -233,6 +233,23 @@ void tty_port_hangup(struct tty_port *port)
233EXPORT_SYMBOL(tty_port_hangup); 233EXPORT_SYMBOL(tty_port_hangup);
234 234
235/** 235/**
236 * tty_port_tty_hangup - helper to hang up a tty
237 *
238 * @port: tty port
239 * @check_clocal: hang only ttys with CLOCAL unset?
240 */
241void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
242{
243 struct tty_struct *tty = tty_port_tty_get(port);
244
245 if (tty && (!check_clocal || !C_CLOCAL(tty))) {
246 tty_hangup(tty);
247 tty_kref_put(tty);
248 }
249}
250EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
251
252/**
236 * tty_port_tty_wakeup - helper to wake up a tty 253 * tty_port_tty_wakeup - helper to wake up a tty
237 * 254 *
238 * @port: tty port 255 * @port: tty port
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 755766e4b756..27a18743275e 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -292,7 +292,6 @@ static void acm_ctrl_irq(struct urb *urb)
292{ 292{
293 struct acm *acm = urb->context; 293 struct acm *acm = urb->context;
294 struct usb_cdc_notification *dr = urb->transfer_buffer; 294 struct usb_cdc_notification *dr = urb->transfer_buffer;
295 struct tty_struct *tty;
296 unsigned char *data; 295 unsigned char *data;
297 int newctrl; 296 int newctrl;
298 int retval; 297 int retval;
@@ -327,17 +326,12 @@ static void acm_ctrl_irq(struct urb *urb)
327 break; 326 break;
328 327
329 case USB_CDC_NOTIFY_SERIAL_STATE: 328 case USB_CDC_NOTIFY_SERIAL_STATE:
330 tty = tty_port_tty_get(&acm->port);
331 newctrl = get_unaligned_le16(data); 329 newctrl = get_unaligned_le16(data);
332 330
333 if (tty) { 331 if (!acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
334 if (!acm->clocal && 332 dev_dbg(&acm->control->dev, "%s - calling hangup\n",
335 (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { 333 __func__);
336 dev_dbg(&acm->control->dev, 334 tty_port_tty_hangup(&acm->port, false);
337 "%s - calling hangup\n", __func__);
338 tty_hangup(tty);
339 }
340 tty_kref_put(tty);
341 } 335 }
342 336
343 acm->ctrlin = newctrl; 337 acm->ctrlin = newctrl;
@@ -1498,15 +1492,9 @@ err_out:
1498static int acm_reset_resume(struct usb_interface *intf) 1492static int acm_reset_resume(struct usb_interface *intf)
1499{ 1493{
1500 struct acm *acm = usb_get_intfdata(intf); 1494 struct acm *acm = usb_get_intfdata(intf);
1501 struct tty_struct *tty;
1502 1495
1503 if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) { 1496 if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags))
1504 tty = tty_port_tty_get(&acm->port); 1497 tty_port_tty_hangup(&acm->port, false);
1505 if (tty) {
1506 tty_hangup(tty);
1507 tty_kref_put(tty);
1508 }
1509 }
1510 1498
1511 return acm_resume(intf); 1499 return acm_resume(intf);
1512} 1500}
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 1fd1935c8316..b011478d2e5f 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -378,7 +378,6 @@ static void usa26_instat_callback(struct urb *urb)
378 struct usb_serial *serial; 378 struct usb_serial *serial;
379 struct usb_serial_port *port; 379 struct usb_serial_port *port;
380 struct keyspan_port_private *p_priv; 380 struct keyspan_port_private *p_priv;
381 struct tty_struct *tty;
382 int old_dcd_state, err; 381 int old_dcd_state, err;
383 int status = urb->status; 382 int status = urb->status;
384 383
@@ -421,12 +420,8 @@ static void usa26_instat_callback(struct urb *urb)
421 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); 420 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
422 p_priv->ri_state = ((msg->ri) ? 1 : 0); 421 p_priv->ri_state = ((msg->ri) ? 1 : 0);
423 422
424 if (old_dcd_state != p_priv->dcd_state) { 423 if (old_dcd_state != p_priv->dcd_state)
425 tty = tty_port_tty_get(&port->port); 424 tty_port_tty_hangup(&port->port, true);
426 if (tty && !C_CLOCAL(tty))
427 tty_hangup(tty);
428 tty_kref_put(tty);
429 }
430 425
431 /* Resubmit urb so we continue receiving */ 426 /* Resubmit urb so we continue receiving */
432 err = usb_submit_urb(urb, GFP_ATOMIC); 427 err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -510,7 +505,6 @@ static void usa28_instat_callback(struct urb *urb)
510 struct usb_serial *serial; 505 struct usb_serial *serial;
511 struct usb_serial_port *port; 506 struct usb_serial_port *port;
512 struct keyspan_port_private *p_priv; 507 struct keyspan_port_private *p_priv;
513 struct tty_struct *tty;
514 int old_dcd_state; 508 int old_dcd_state;
515 int status = urb->status; 509 int status = urb->status;
516 510
@@ -551,12 +545,8 @@ static void usa28_instat_callback(struct urb *urb)
551 p_priv->dcd_state = ((msg->dcd) ? 1 : 0); 545 p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
552 p_priv->ri_state = ((msg->ri) ? 1 : 0); 546 p_priv->ri_state = ((msg->ri) ? 1 : 0);
553 547
554 if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { 548 if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
555 tty = tty_port_tty_get(&port->port); 549 tty_port_tty_hangup(&port->port, true);
556 if (tty && !C_CLOCAL(tty))
557 tty_hangup(tty);
558 tty_kref_put(tty);
559 }
560 550
561 /* Resubmit urb so we continue receiving */ 551 /* Resubmit urb so we continue receiving */
562 err = usb_submit_urb(urb, GFP_ATOMIC); 552 err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -642,12 +632,8 @@ static void usa49_instat_callback(struct urb *urb)
642 p_priv->dcd_state = ((msg->dcd) ? 1 : 0); 632 p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
643 p_priv->ri_state = ((msg->ri) ? 1 : 0); 633 p_priv->ri_state = ((msg->ri) ? 1 : 0);
644 634
645 if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { 635 if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
646 struct tty_struct *tty = tty_port_tty_get(&port->port); 636 tty_port_tty_hangup(&port->port, true);
647 if (tty && !C_CLOCAL(tty))
648 tty_hangup(tty);
649 tty_kref_put(tty);
650 }
651 637
652 /* Resubmit urb so we continue receiving */ 638 /* Resubmit urb so we continue receiving */
653 err = usb_submit_urb(urb, GFP_ATOMIC); 639 err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -851,7 +837,6 @@ static void usa90_instat_callback(struct urb *urb)
851 struct usb_serial *serial; 837 struct usb_serial *serial;
852 struct usb_serial_port *port; 838 struct usb_serial_port *port;
853 struct keyspan_port_private *p_priv; 839 struct keyspan_port_private *p_priv;
854 struct tty_struct *tty;
855 int old_dcd_state, err; 840 int old_dcd_state, err;
856 int status = urb->status; 841 int status = urb->status;
857 842
@@ -880,12 +865,8 @@ static void usa90_instat_callback(struct urb *urb)
880 p_priv->dcd_state = ((msg->dcd) ? 1 : 0); 865 p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
881 p_priv->ri_state = ((msg->ri) ? 1 : 0); 866 p_priv->ri_state = ((msg->ri) ? 1 : 0);
882 867
883 if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { 868 if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
884 tty = tty_port_tty_get(&port->port); 869 tty_port_tty_hangup(&port->port, true);
885 if (tty && !C_CLOCAL(tty))
886 tty_hangup(tty);
887 tty_kref_put(tty);
888 }
889 870
890 /* Resubmit urb so we continue receiving */ 871 /* Resubmit urb so we continue receiving */
891 err = usb_submit_urb(urb, GFP_ATOMIC); 872 err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -953,12 +934,8 @@ static void usa67_instat_callback(struct urb *urb)
953 p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0); 934 p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
954 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); 935 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
955 936
956 if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { 937 if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
957 struct tty_struct *tty = tty_port_tty_get(&port->port); 938 tty_port_tty_hangup(&port->port, true);
958 if (tty && !C_CLOCAL(tty))
959 tty_hangup(tty);
960 tty_kref_put(tty);
961 }
962 939
963 /* Resubmit urb so we continue receiving */ 940 /* Resubmit urb so we continue receiving */
964 err = usb_submit_urb(urb, GFP_ATOMIC); 941 err = usb_submit_urb(urb, GFP_ATOMIC);
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index f7d339d8187b..602d1f389a3b 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1532,13 +1532,8 @@ static void option_instat_callback(struct urb *urb)
1532 portdata->dsr_state = ((signals & 0x02) ? 1 : 0); 1532 portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
1533 portdata->ri_state = ((signals & 0x08) ? 1 : 0); 1533 portdata->ri_state = ((signals & 0x08) ? 1 : 0);
1534 1534
1535 if (old_dcd_state && !portdata->dcd_state) { 1535 if (old_dcd_state && !portdata->dcd_state)
1536 struct tty_struct *tty = 1536 tty_port_tty_hangup(&port->port, true);
1537 tty_port_tty_get(&port->port);
1538 if (tty && !C_CLOCAL(tty))
1539 tty_hangup(tty);
1540 tty_kref_put(tty);
1541 }
1542 } else { 1537 } else {
1543 dev_dbg(dev, "%s: type %x req %x\n", __func__, 1538 dev_dbg(dev, "%s: type %x req %x\n", __func__,
1544 req_pkt->bRequestType, req_pkt->bRequest); 1539 req_pkt->bRequestType, req_pkt->bRequest);
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index c13f6e747748..d66148a17fe3 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -628,7 +628,6 @@ static void sierra_instat_callback(struct urb *urb)
628 unsigned char signals = *((unsigned char *) 628 unsigned char signals = *((unsigned char *)
629 urb->transfer_buffer + 629 urb->transfer_buffer +
630 sizeof(struct usb_ctrlrequest)); 630 sizeof(struct usb_ctrlrequest));
631 struct tty_struct *tty;
632 631
633 dev_dbg(&port->dev, "%s: signal x%x\n", __func__, 632 dev_dbg(&port->dev, "%s: signal x%x\n", __func__,
634 signals); 633 signals);
@@ -639,11 +638,8 @@ static void sierra_instat_callback(struct urb *urb)
639 portdata->dsr_state = ((signals & 0x02) ? 1 : 0); 638 portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
640 portdata->ri_state = ((signals & 0x08) ? 1 : 0); 639 portdata->ri_state = ((signals & 0x08) ? 1 : 0);
641 640
642 tty = tty_port_tty_get(&port->port); 641 if (old_dcd_state && !portdata->dcd_state)
643 if (tty && !C_CLOCAL(tty) && 642 tty_port_tty_hangup(&port->port, true);
644 old_dcd_state && !portdata->dcd_state)
645 tty_hangup(tty);
646 tty_kref_put(tty);
647 } else { 643 } else {
648 dev_dbg(&port->dev, "%s: type %x req %x\n", 644 dev_dbg(&port->dev, "%s: type %x req %x\n",
649 __func__, req_pkt->bRequestType, 645 __func__, req_pkt->bRequestType,
diff --git a/include/linux/tty.h b/include/linux/tty.h
index b6e890a87eb1..d3548f871968 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -534,6 +534,7 @@ extern int tty_port_carrier_raised(struct tty_port *port);
534extern void tty_port_raise_dtr_rts(struct tty_port *port); 534extern void tty_port_raise_dtr_rts(struct tty_port *port);
535extern void tty_port_lower_dtr_rts(struct tty_port *port); 535extern void tty_port_lower_dtr_rts(struct tty_port *port);
536extern void tty_port_hangup(struct tty_port *port); 536extern void tty_port_hangup(struct tty_port *port);
537extern void tty_port_tty_hangup(struct tty_port *port, bool check_clocal);
537extern void tty_port_tty_wakeup(struct tty_port *port); 538extern void tty_port_tty_wakeup(struct tty_port *port);
538extern int tty_port_block_til_ready(struct tty_port *port, 539extern int tty_port_block_til_ready(struct tty_port *port,
539 struct tty_struct *tty, struct file *filp); 540 struct tty_struct *tty, struct file *filp);
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c
index edab393e0c82..a2a508f5f268 100644
--- a/net/irda/ircomm/ircomm_tty_attach.c
+++ b/net/irda/ircomm/ircomm_tty_attach.c
@@ -997,12 +997,8 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self,
997 self->settings.dce = IRCOMM_DELTA_CD; 997 self->settings.dce = IRCOMM_DELTA_CD;
998 ircomm_tty_check_modem_status(self); 998 ircomm_tty_check_modem_status(self);
999 } else { 999 } else {
1000 struct tty_struct *tty = tty_port_tty_get(&self->port);
1001 IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ ); 1000 IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ );
1002 if (tty) { 1001 tty_port_tty_hangup(&self->port, false);
1003 tty_hangup(tty);
1004 tty_kref_put(tty);
1005 }
1006 } 1002 }
1007 break; 1003 break;
1008 default: 1004 default: