Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jiri Slaby and committed by
Greg Kroah-Hartman
aa27a094 e4408ce3

+58 -148
+1 -5
arch/um/drivers/chan_kern.c
··· 568 568 reactivate_fd(chan->fd, irq); 569 569 if (err == -EIO) { 570 570 if (chan->primary) { 571 - struct tty_struct *tty = tty_port_tty_get(&line->port); 572 - if (tty != NULL) { 573 - tty_hangup(tty); 574 - tty_kref_put(tty); 575 - } 571 + tty_port_tty_hangup(&line->port, false); 576 572 if (line->chan_out != chan) 577 573 close_one_chan(line->chan_out, 1); 578 574 }
+2 -11
drivers/mmc/card/sdio_uart.c
··· 134 134 static void sdio_uart_port_remove(struct sdio_uart_port *port) 135 135 { 136 136 struct sdio_func *func; 137 - struct tty_struct *tty; 138 137 139 138 BUG_ON(sdio_uart_table[port->index] != port); 140 139 ··· 154 155 sdio_claim_host(func); 155 156 port->func = NULL; 156 157 mutex_unlock(&port->func_lock); 157 - tty = tty_port_tty_get(&port->port); 158 158 /* tty_hangup is async so is this safe as is ?? */ 159 - if (tty) { 160 - tty_hangup(tty); 161 - tty_kref_put(tty); 162 - } 159 + tty_port_tty_hangup(&port->port, false); 163 160 mutex_unlock(&port->port.mutex); 164 161 sdio_release_irq(func); 165 162 sdio_disable_func(func); ··· 487 492 wake_up_interruptible(&port->port.open_wait); 488 493 else { 489 494 /* DCD drop - hang up if tty attached */ 490 - tty = tty_port_tty_get(&port->port); 491 - if (tty) { 492 - tty_hangup(tty); 493 - tty_kref_put(tty); 494 - } 495 + tty_port_tty_hangup(&port->port, false); 495 496 } 496 497 } 497 498 if (status & UART_MSR_DCTS) {
+1 -6
drivers/net/usb/hso.c
··· 3124 3124 static void hso_free_interface(struct usb_interface *interface) 3125 3125 { 3126 3126 struct hso_serial *hso_dev; 3127 - struct tty_struct *tty; 3128 3127 int i; 3129 3128 3130 3129 for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { 3131 3130 if (serial_table[i] && 3132 3131 (serial_table[i]->interface == interface)) { 3133 3132 hso_dev = dev2ser(serial_table[i]); 3134 - tty = tty_port_tty_get(&hso_dev->port); 3135 - if (tty) { 3136 - tty_hangup(tty); 3137 - tty_kref_put(tty); 3138 - } 3133 + tty_port_tty_hangup(&hso_dev->port, false); 3139 3134 mutex_lock(&hso_dev->parent->mutex); 3140 3135 hso_dev->parent->usb_gone = 1; 3141 3136 mutex_unlock(&hso_dev->parent->mutex);
+2 -8
drivers/tty/cyclades.c
··· 1124 1124 readl(&info->u.cyz.ch_ctrl->rs_status); 1125 1125 if (dcd & C_RS_DCD) 1126 1126 wake_up_interruptible(&info->port.open_wait); 1127 - else { 1128 - struct tty_struct *tty; 1129 - tty = tty_port_tty_get(&info->port); 1130 - if (tty) { 1131 - tty_hangup(tty); 1132 - tty_kref_put(tty); 1133 - } 1134 - } 1127 + else 1128 + tty_port_tty_hangup(&info->port, false); 1135 1129 } 1136 1130 break; 1137 1131 case C_CM_MCTS:
+6 -13
drivers/tty/moxa.c
··· 913 913 914 914 /* pci hot-un-plug support */ 915 915 for (a = 0; a < brd->numPorts; a++) 916 - if (brd->ports[a].port.flags & ASYNC_INITIALIZED) { 917 - struct tty_struct *tty = tty_port_tty_get( 918 - &brd->ports[a].port); 919 - if (tty) { 920 - tty_hangup(tty); 921 - tty_kref_put(tty); 922 - } 923 - } 916 + if (brd->ports[a].port.flags & ASYNC_INITIALIZED) 917 + tty_port_tty_hangup(&brd->ports[a].port, false); 918 + 924 919 for (a = 0; a < MAX_PORTS_PER_BOARD; a++) 925 920 tty_port_destroy(&brd->ports[a].port); 921 + 926 922 while (1) { 927 923 opened = 0; 928 924 for (a = 0; a < brd->numPorts; a++) ··· 1361 1365 1362 1366 static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) 1363 1367 { 1364 - struct tty_struct *tty; 1365 1368 unsigned long flags; 1366 1369 dcd = !!dcd; 1367 1370 ··· 1368 1373 if (dcd != p->DCDState) { 1369 1374 p->DCDState = dcd; 1370 1375 spin_unlock_irqrestore(&p->port.lock, flags); 1371 - tty = tty_port_tty_get(&p->port); 1372 - if (tty && !C_CLOCAL(tty) && !dcd) 1373 - tty_hangup(tty); 1374 - tty_kref_put(tty); 1376 + if (!dcd) 1377 + tty_port_tty_hangup(&p->port, true); 1375 1378 } 1376 1379 else 1377 1380 spin_unlock_irqrestore(&p->port.lock, flags);
+1 -5
drivers/tty/n_gsm.c
··· 1418 1418 pr_debug("DLCI %d goes closed.\n", dlci->addr); 1419 1419 dlci->state = DLCI_CLOSED; 1420 1420 if (dlci->addr != 0) { 1421 - struct tty_struct *tty = tty_port_tty_get(&dlci->port); 1422 - if (tty) { 1423 - tty_hangup(tty); 1424 - tty_kref_put(tty); 1425 - } 1421 + tty_port_tty_hangup(&dlci->port, false); 1426 1422 kfifo_reset(dlci->fifo); 1427 1423 } else 1428 1424 dlci->gsm->dead = 1;
+3 -6
drivers/tty/nozomi.c
··· 1501 1501 1502 1502 DBG1(" "); 1503 1503 1504 - for (i = 0; i < MAX_PORT; ++i) { 1505 - struct tty_struct *tty = tty_port_tty_get(&dc->port[i].port); 1506 - if (tty && list_empty(&tty->hangup_work.entry)) 1507 - tty_hangup(tty); 1508 - tty_kref_put(tty); 1509 - } 1504 + for (i = 0; i < MAX_PORT; ++i) 1505 + tty_port_tty_hangup(&dc->port[i].port, false); 1506 + 1510 1507 /* Racy below - surely should wait for scheduled work to be done or 1511 1508 complete off a hangup method ? */ 1512 1509 while (dc->open_ttys)
+1 -6
drivers/tty/rocket.c
··· 521 521 (ChanStatus & CD_ACT) ? "on" : "off"); 522 522 #endif 523 523 if (!(ChanStatus & CD_ACT) && info->cd_status) { 524 - struct tty_struct *tty; 525 524 #ifdef ROCKET_DEBUG_HANGUP 526 525 printk(KERN_INFO "CD drop, calling hangup.\n"); 527 526 #endif 528 - tty = tty_port_tty_get(&info->port); 529 - if (tty) { 530 - tty_hangup(tty); 531 - tty_kref_put(tty); 532 - } 527 + tty_port_tty_hangup(&info->port, false); 533 528 } 534 529 info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0; 535 530 wake_up_interruptible(&info->port.open_wait);
+2 -19
drivers/tty/serial/ifx6x60.c
··· 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 - */ 279 - static 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 273 * ifx_spi_timeout - SPI timeout 291 274 * @arg: our SPI device 292 275 * ··· 281 298 struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *)arg; 282 299 283 300 dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***"); 284 - ifx_spi_ttyhangup(ifx_dev); 301 + tty_port_tty_hangup(&ifx_dev->tty_port, false); 285 302 mrdy_set_low(ifx_dev); 286 303 clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); 287 304 } ··· 916 933 set_bit(MR_INPROGRESS, &ifx_dev->mdm_reset_state); 917 934 if (!solreset) { 918 935 /* unsolicited reset */ 919 - ifx_spi_ttyhangup(ifx_dev); 936 + tty_port_tty_hangup(&ifx_dev->tty_port, false); 920 937 } 921 938 } else { 922 939 /* exited reset */
+17
drivers/tty/tty_port.c
··· 233 233 EXPORT_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 + */ 241 + void 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 + } 250 + EXPORT_SYMBOL_GPL(tty_port_tty_hangup); 251 + 252 + /** 236 253 * tty_port_tty_wakeup - helper to wake up a tty 237 254 * 238 255 * @port: tty port
+6 -18
drivers/usb/class/cdc-acm.c
··· 292 292 { 293 293 struct acm *acm = urb->context; 294 294 struct usb_cdc_notification *dr = urb->transfer_buffer; 295 - struct tty_struct *tty; 296 295 unsigned char *data; 297 296 int newctrl; 298 297 int retval; ··· 326 327 break; 327 328 328 329 case USB_CDC_NOTIFY_SERIAL_STATE: 329 - tty = tty_port_tty_get(&acm->port); 330 330 newctrl = get_unaligned_le16(data); 331 331 332 - if (tty) { 333 - if (!acm->clocal && 334 - (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { 335 - dev_dbg(&acm->control->dev, 336 - "%s - calling hangup\n", __func__); 337 - tty_hangup(tty); 338 - } 339 - tty_kref_put(tty); 332 + if (!acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { 333 + dev_dbg(&acm->control->dev, "%s - calling hangup\n", 334 + __func__); 335 + tty_port_tty_hangup(&acm->port, false); 340 336 } 341 337 342 338 acm->ctrlin = newctrl; ··· 1492 1498 static int acm_reset_resume(struct usb_interface *intf) 1493 1499 { 1494 1500 struct acm *acm = usb_get_intfdata(intf); 1495 - struct tty_struct *tty; 1496 1501 1497 - if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) { 1498 - tty = tty_port_tty_get(&acm->port); 1499 - if (tty) { 1500 - tty_hangup(tty); 1501 - tty_kref_put(tty); 1502 - } 1503 - } 1502 + if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) 1503 + tty_port_tty_hangup(&acm->port, false); 1504 1504 1505 1505 return acm_resume(intf); 1506 1506 }
+10 -33
drivers/usb/serial/keyspan.c
··· 378 378 struct usb_serial *serial; 379 379 struct usb_serial_port *port; 380 380 struct keyspan_port_private *p_priv; 381 - struct tty_struct *tty; 382 381 int old_dcd_state, err; 383 382 int status = urb->status; 384 383 ··· 420 421 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); 421 422 p_priv->ri_state = ((msg->ri) ? 1 : 0); 422 423 423 - if (old_dcd_state != p_priv->dcd_state) { 424 - tty = tty_port_tty_get(&port->port); 425 - if (tty && !C_CLOCAL(tty)) 426 - tty_hangup(tty); 427 - tty_kref_put(tty); 428 - } 424 + if (old_dcd_state != p_priv->dcd_state) 425 + tty_port_tty_hangup(&port->port, true); 429 426 430 427 /* Resubmit urb so we continue receiving */ 431 428 err = usb_submit_urb(urb, GFP_ATOMIC); ··· 505 510 struct usb_serial *serial; 506 511 struct usb_serial_port *port; 507 512 struct keyspan_port_private *p_priv; 508 - struct tty_struct *tty; 509 513 int old_dcd_state; 510 514 int status = urb->status; 511 515 ··· 545 551 p_priv->dcd_state = ((msg->dcd) ? 1 : 0); 546 552 p_priv->ri_state = ((msg->ri) ? 1 : 0); 547 553 548 - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { 549 - tty = tty_port_tty_get(&port->port); 550 - if (tty && !C_CLOCAL(tty)) 551 - tty_hangup(tty); 552 - tty_kref_put(tty); 553 - } 554 + if (old_dcd_state != p_priv->dcd_state && old_dcd_state) 555 + tty_port_tty_hangup(&port->port, true); 554 556 555 557 /* Resubmit urb so we continue receiving */ 556 558 err = usb_submit_urb(urb, GFP_ATOMIC); ··· 632 642 p_priv->dcd_state = ((msg->dcd) ? 1 : 0); 633 643 p_priv->ri_state = ((msg->ri) ? 1 : 0); 634 644 635 - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { 636 - struct tty_struct *tty = tty_port_tty_get(&port->port); 637 - if (tty && !C_CLOCAL(tty)) 638 - tty_hangup(tty); 639 - tty_kref_put(tty); 640 - } 645 + if (old_dcd_state != p_priv->dcd_state && old_dcd_state) 646 + tty_port_tty_hangup(&port->port, true); 641 647 642 648 /* Resubmit urb so we continue receiving */ 643 649 err = usb_submit_urb(urb, GFP_ATOMIC); ··· 837 851 struct usb_serial *serial; 838 852 struct usb_serial_port *port; 839 853 struct keyspan_port_private *p_priv; 840 - struct tty_struct *tty; 841 854 int old_dcd_state, err; 842 855 int status = urb->status; 843 856 ··· 865 880 p_priv->dcd_state = ((msg->dcd) ? 1 : 0); 866 881 p_priv->ri_state = ((msg->ri) ? 1 : 0); 867 882 868 - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { 869 - tty = tty_port_tty_get(&port->port); 870 - if (tty && !C_CLOCAL(tty)) 871 - tty_hangup(tty); 872 - tty_kref_put(tty); 873 - } 883 + if (old_dcd_state != p_priv->dcd_state && old_dcd_state) 884 + tty_port_tty_hangup(&port->port, true); 874 885 875 886 /* Resubmit urb so we continue receiving */ 876 887 err = usb_submit_urb(urb, GFP_ATOMIC); ··· 934 953 p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0); 935 954 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); 936 955 937 - if (old_dcd_state != p_priv->dcd_state && old_dcd_state) { 938 - struct tty_struct *tty = tty_port_tty_get(&port->port); 939 - if (tty && !C_CLOCAL(tty)) 940 - tty_hangup(tty); 941 - tty_kref_put(tty); 942 - } 956 + if (old_dcd_state != p_priv->dcd_state && old_dcd_state) 957 + tty_port_tty_hangup(&port->port, true); 943 958 944 959 /* Resubmit urb so we continue receiving */ 945 960 err = usb_submit_urb(urb, GFP_ATOMIC);
+2 -7
drivers/usb/serial/option.c
··· 1532 1532 portdata->dsr_state = ((signals & 0x02) ? 1 : 0); 1533 1533 portdata->ri_state = ((signals & 0x08) ? 1 : 0); 1534 1534 1535 - if (old_dcd_state && !portdata->dcd_state) { 1536 - struct tty_struct *tty = 1537 - tty_port_tty_get(&port->port); 1538 - if (tty && !C_CLOCAL(tty)) 1539 - tty_hangup(tty); 1540 - tty_kref_put(tty); 1541 - } 1535 + if (old_dcd_state && !portdata->dcd_state) 1536 + tty_port_tty_hangup(&port->port, true); 1542 1537 } else { 1543 1538 dev_dbg(dev, "%s: type %x req %x\n", __func__, 1544 1539 req_pkt->bRequestType, req_pkt->bRequest);
+2 -6
drivers/usb/serial/sierra.c
··· 628 628 unsigned char signals = *((unsigned char *) 629 629 urb->transfer_buffer + 630 630 sizeof(struct usb_ctrlrequest)); 631 - struct tty_struct *tty; 632 631 633 632 dev_dbg(&port->dev, "%s: signal x%x\n", __func__, 634 633 signals); ··· 638 639 portdata->dsr_state = ((signals & 0x02) ? 1 : 0); 639 640 portdata->ri_state = ((signals & 0x08) ? 1 : 0); 640 641 641 - tty = tty_port_tty_get(&port->port); 642 - if (tty && !C_CLOCAL(tty) && 643 - old_dcd_state && !portdata->dcd_state) 644 - tty_hangup(tty); 645 - tty_kref_put(tty); 642 + if (old_dcd_state && !portdata->dcd_state) 643 + tty_port_tty_hangup(&port->port, true); 646 644 } else { 647 645 dev_dbg(&port->dev, "%s: type %x req %x\n", 648 646 __func__, req_pkt->bRequestType,
+1
include/linux/tty.h
··· 534 534 extern void tty_port_raise_dtr_rts(struct tty_port *port); 535 535 extern void tty_port_lower_dtr_rts(struct tty_port *port); 536 536 extern void tty_port_hangup(struct tty_port *port); 537 + extern void tty_port_tty_hangup(struct tty_port *port, bool check_clocal); 537 538 extern void tty_port_tty_wakeup(struct tty_port *port); 538 539 extern int tty_port_block_til_ready(struct tty_port *port, 539 540 struct tty_struct *tty, struct file *filp);
+1 -5
net/irda/ircomm/ircomm_tty_attach.c
··· 997 997 self->settings.dce = IRCOMM_DELTA_CD; 998 998 ircomm_tty_check_modem_status(self); 999 999 } else { 1000 - struct tty_struct *tty = tty_port_tty_get(&self->port); 1001 1000 IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ ); 1002 - if (tty) { 1003 - tty_hangup(tty); 1004 - tty_kref_put(tty); 1005 - } 1001 + tty_port_tty_hangup(&self->port, false); 1006 1002 } 1007 1003 break; 1008 1004 default: