TTY: add tty_port_tty_hangup helper
authorJiri Slaby <jslaby@suse.cz>
Thu, 7 Mar 2013 12:12:30 +0000 (13:12 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 18 Mar 2013 23:24:29 +0000 (16:24 -0700)
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>
16 files changed:
arch/um/drivers/chan_kern.c
drivers/mmc/card/sdio_uart.c
drivers/net/usb/hso.c
drivers/tty/cyclades.c
drivers/tty/moxa.c
drivers/tty/n_gsm.c
drivers/tty/nozomi.c
drivers/tty/rocket.c
drivers/tty/serial/ifx6x60.c
drivers/tty/tty_port.c
drivers/usb/class/cdc-acm.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/option.c
drivers/usb/serial/sierra.c
include/linux/tty.h
net/irda/ircomm/ircomm_tty_attach.c

index 15c553c239a119259f2f948f8381e5a9a26f4ccb..bf42825ba54f4ecc527d84eae021783affcf50c6 100644 (file)
@@ -568,11 +568,7 @@ void chan_interrupt(struct line *line, int irq)
                reactivate_fd(chan->fd, irq);
        if (err == -EIO) {
                if (chan->primary) {
-                       struct tty_struct *tty = tty_port_tty_get(&line->port);
-                       if (tty != NULL) {
-                               tty_hangup(tty);
-                               tty_kref_put(tty);
-                       }
+                       tty_port_tty_hangup(&line->port, false);
                        if (line->chan_out != chan)
                                close_one_chan(line->chan_out, 1);
                }
index c931dfe6a59cb80ac893d3d2754eac7b9a07301d..f093cea0d0600797cc1574c6f85a25dac5c128fc 100644 (file)
@@ -134,7 +134,6 @@ static void sdio_uart_port_put(struct sdio_uart_port *port)
 static void sdio_uart_port_remove(struct sdio_uart_port *port)
 {
        struct sdio_func *func;
-       struct tty_struct *tty;
 
        BUG_ON(sdio_uart_table[port->index] != port);
 
@@ -155,12 +154,8 @@ static void sdio_uart_port_remove(struct sdio_uart_port *port)
        sdio_claim_host(func);
        port->func = NULL;
        mutex_unlock(&port->func_lock);
-       tty = tty_port_tty_get(&port->port);
        /* tty_hangup is async so is this safe as is ?? */
-       if (tty) {
-               tty_hangup(tty);
-               tty_kref_put(tty);
-       }
+       tty_port_tty_hangup(&port->port, false);
        mutex_unlock(&port->port.mutex);
        sdio_release_irq(func);
        sdio_disable_func(func);
@@ -492,11 +487,7 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
                        wake_up_interruptible(&port->port.open_wait);
                else {
                        /* DCD drop - hang up if tty attached */
-                       tty = tty_port_tty_get(&port->port);
-                       if (tty) {
-                               tty_hangup(tty);
-                               tty_kref_put(tty);
-                       }
+                       tty_port_tty_hangup(&port->port, false);
                }
        }
        if (status & UART_MSR_DCTS) {
index a7714b4f29adf4df0ddc761c122e350c90b0c8f0..cba1d46e672e4cde205fbbd36fb79275cd1ecc53 100644 (file)
@@ -3124,18 +3124,13 @@ static void hso_serial_ref_free(struct kref *ref)
 static void hso_free_interface(struct usb_interface *interface)
 {
        struct hso_serial *hso_dev;
-       struct tty_struct *tty;
        int i;
 
        for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
                if (serial_table[i] &&
                    (serial_table[i]->interface == interface)) {
                        hso_dev = dev2ser(serial_table[i]);
-                       tty = tty_port_tty_get(&hso_dev->port);
-                       if (tty) {
-                               tty_hangup(tty);
-                               tty_kref_put(tty);
-                       }
+                       tty_port_tty_hangup(&hso_dev->port, false);
                        mutex_lock(&hso_dev->parent->mutex);
                        hso_dev->parent->usb_gone = 1;
                        mutex_unlock(&hso_dev->parent->mutex);
index 345bd0e0884ef73439be07a4d81741bd7a78732e..33f83fee9faec6be78206ebbc4aeee5ba1702fc8 100644 (file)
@@ -1124,14 +1124,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
                                        readl(&info->u.cyz.ch_ctrl->rs_status);
                                if (dcd & C_RS_DCD)
                                        wake_up_interruptible(&info->port.open_wait);
-                               else {
-                                       struct tty_struct *tty;
-                                       tty = tty_port_tty_get(&info->port);
-                                       if (tty) {
-                                               tty_hangup(tty);
-                                               tty_kref_put(tty);
-                                       }
-                               }
+                               else
+                                       tty_port_tty_hangup(&info->port, false);
                        }
                        break;
                case C_CM_MCTS:
index adeac255e526879c1d0e02ba9a747115970a1842..1deaca4674e4405fb925a50fbd289f3b9b5c74b6 100644 (file)
@@ -913,16 +913,12 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
 
        /* pci hot-un-plug support */
        for (a = 0; a < brd->numPorts; a++)
-               if (brd->ports[a].port.flags & ASYNC_INITIALIZED) {
-                       struct tty_struct *tty = tty_port_tty_get(
-                                               &brd->ports[a].port);
-                       if (tty) {
-                               tty_hangup(tty);
-                               tty_kref_put(tty);
-                       }
-               }
+               if (brd->ports[a].port.flags & ASYNC_INITIALIZED)
+                       tty_port_tty_hangup(&brd->ports[a].port, false);
+
        for (a = 0; a < MAX_PORTS_PER_BOARD; a++)
                tty_port_destroy(&brd->ports[a].port);
+
        while (1) {
                opened = 0;
                for (a = 0; a < brd->numPorts; a++)
@@ -1365,7 +1361,6 @@ static void moxa_hangup(struct tty_struct *tty)
 
 static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
 {
-       struct tty_struct *tty;
        unsigned long flags;
        dcd = !!dcd;
 
@@ -1373,10 +1368,8 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
        if (dcd != p->DCDState) {
                p->DCDState = dcd;
                spin_unlock_irqrestore(&p->port.lock, flags);
-               tty = tty_port_tty_get(&p->port);
-               if (tty && !C_CLOCAL(tty) && !dcd)
-                       tty_hangup(tty);
-               tty_kref_put(tty);
+               if (!dcd)
+                       tty_port_tty_hangup(&p->port, true);
        }
        else
                spin_unlock_irqrestore(&p->port.lock, flags);
index 4a43ef5d7962c9b043dc047ac16a5207f656bfa7..74d9a0258d7c2126c3e34a2781e8ecf03c7281d3 100644 (file)
@@ -1418,11 +1418,7 @@ static void gsm_dlci_close(struct gsm_dlci *dlci)
                pr_debug("DLCI %d goes closed.\n", dlci->addr);
        dlci->state = DLCI_CLOSED;
        if (dlci->addr != 0) {
-               struct tty_struct  *tty = tty_port_tty_get(&dlci->port);
-               if (tty) {
-                       tty_hangup(tty);
-                       tty_kref_put(tty);
-               }
+               tty_port_tty_hangup(&dlci->port, false);
                kfifo_reset(dlci->fifo);
        } else
                dlci->gsm->dead = 1;
index 2e5bbdc09e1ce3d671e462dae35906f7b2a2c0aa..d6080c3831ef98b72d8269dc3750f58f6d55bfba 100644 (file)
@@ -1501,12 +1501,9 @@ static void tty_exit(struct nozomi *dc)
 
        DBG1(" ");
 
-       for (i = 0; i < MAX_PORT; ++i) {
-               struct tty_struct *tty = tty_port_tty_get(&dc->port[i].port);
-               if (tty && list_empty(&tty->hangup_work.entry))
-                       tty_hangup(tty);
-               tty_kref_put(tty);
-       }
+       for (i = 0; i < MAX_PORT; ++i)
+               tty_port_tty_hangup(&dc->port[i].port, false);
+
        /* Racy below - surely should wait for scheduled work to be done or
           complete off a hangup method ? */
        while (dc->open_ttys)
index 1d270034bfc33e78a2665f61edfdec6caba8097e..bbffd7a431e97d0d17b8c37e0d492586f1f00745 100644 (file)
@@ -521,15 +521,10 @@ static void rp_handle_port(struct r_port *info)
                       (ChanStatus & CD_ACT) ? "on" : "off");
 #endif
                if (!(ChanStatus & CD_ACT) && info->cd_status) {
-                       struct tty_struct *tty;
 #ifdef ROCKET_DEBUG_HANGUP
                        printk(KERN_INFO "CD drop, calling hangup.\n");
 #endif
-                       tty = tty_port_tty_get(&info->port);
-                       if (tty) {
-                               tty_hangup(tty);
-                               tty_kref_put(tty);
-                       }
+                       tty_port_tty_hangup(&info->port, false);
                }
                info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0;
                wake_up_interruptible(&info->port.open_wait);
index d723d4193b9014a6bc1730b106798d22fe9ca59d..2c77fed31a72f7d87c1c98e457699fafba95e4d0 100644 (file)
@@ -269,23 +269,6 @@ static void mrdy_assert(struct ifx_spi_device *ifx_dev)
        mrdy_set_high(ifx_dev);
 }
 
-/**
- *     ifx_spi_hangup          -       hang up an IFX device
- *     @ifx_dev: our SPI device
- *
- *     Hang up the tty attached to the IFX device if one is currently
- *     open. If not take no action
- */
-static void ifx_spi_ttyhangup(struct ifx_spi_device *ifx_dev)
-{
-       struct tty_port *pport = &ifx_dev->tty_port;
-       struct tty_struct *tty = tty_port_tty_get(pport);
-       if (tty) {
-               tty_hangup(tty);
-               tty_kref_put(tty);
-       }
-}
-
 /**
  *     ifx_spi_timeout         -       SPI timeout
  *     @arg: our SPI device
@@ -298,7 +281,7 @@ static void ifx_spi_timeout(unsigned long arg)
        struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *)arg;
 
        dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***");
-       ifx_spi_ttyhangup(ifx_dev);
+       tty_port_tty_hangup(&ifx_dev->tty_port, false);
        mrdy_set_low(ifx_dev);
        clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
 }
@@ -933,7 +916,7 @@ static irqreturn_t ifx_spi_reset_interrupt(int irq, void *dev)
                set_bit(MR_INPROGRESS, &ifx_dev->mdm_reset_state);
                if (!solreset) {
                        /* unsolicited reset  */
-                       ifx_spi_ttyhangup(ifx_dev);
+                       tty_port_tty_hangup(&ifx_dev->tty_port, false);
                }
        } else {
                /* exited reset */
index 8bb757c62ee2044746cd9e93a052325bc28907db..7f38eeaafac3d1036c2307d99fb25d265a253503 100644 (file)
@@ -232,6 +232,23 @@ void tty_port_hangup(struct tty_port *port)
 }
 EXPORT_SYMBOL(tty_port_hangup);
 
+/**
+ * tty_port_tty_hangup - helper to hang up a tty
+ *
+ * @port: tty port
+ * @check_clocal: hang only ttys with CLOCAL unset?
+ */
+void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
+{
+       struct tty_struct *tty = tty_port_tty_get(port);
+
+       if (tty && (!check_clocal || !C_CLOCAL(tty))) {
+               tty_hangup(tty);
+               tty_kref_put(tty);
+       }
+}
+EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
+
 /**
  * tty_port_tty_wakeup - helper to wake up a tty
  *
index 755766e4b7566d2a9fa236cd5ce919ba97a9a23e..27a18743275e8ac8934ef06316f625c3f0cb2352 100644 (file)
@@ -292,7 +292,6 @@ static void acm_ctrl_irq(struct urb *urb)
 {
        struct acm *acm = urb->context;
        struct usb_cdc_notification *dr = urb->transfer_buffer;
-       struct tty_struct *tty;
        unsigned char *data;
        int newctrl;
        int retval;
@@ -327,17 +326,12 @@ static void acm_ctrl_irq(struct urb *urb)
                break;
 
        case USB_CDC_NOTIFY_SERIAL_STATE:
-               tty = tty_port_tty_get(&acm->port);
                newctrl = get_unaligned_le16(data);
 
-               if (tty) {
-                       if (!acm->clocal &&
-                               (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
-                               dev_dbg(&acm->control->dev,
-                                       "%s - calling hangup\n", __func__);
-                               tty_hangup(tty);
-                       }
-                       tty_kref_put(tty);
+               if (!acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
+                       dev_dbg(&acm->control->dev, "%s - calling hangup\n",
+                                       __func__);
+                       tty_port_tty_hangup(&acm->port, false);
                }
 
                acm->ctrlin = newctrl;
@@ -1498,15 +1492,9 @@ err_out:
 static int acm_reset_resume(struct usb_interface *intf)
 {
        struct acm *acm = usb_get_intfdata(intf);
-       struct tty_struct *tty;
 
-       if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {
-               tty = tty_port_tty_get(&acm->port);
-               if (tty) {
-                       tty_hangup(tty);
-                       tty_kref_put(tty);
-               }
-       }
+       if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags))
+               tty_port_tty_hangup(&acm->port, false);
 
        return acm_resume(intf);
 }
index 1fd1935c8316f525e5795c22fa0dada0093b6be9..b011478d2e5f43cffc8923f3264d69d9a4facceb 100644 (file)
@@ -378,7 +378,6 @@ static void usa26_instat_callback(struct urb *urb)
        struct usb_serial                       *serial;
        struct usb_serial_port                  *port;
        struct keyspan_port_private             *p_priv;
-       struct tty_struct                       *tty;
        int old_dcd_state, err;
        int status = urb->status;
 
@@ -421,12 +420,8 @@ static void        usa26_instat_callback(struct urb *urb)
        p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
        p_priv->ri_state = ((msg->ri) ? 1 : 0);
 
-       if (old_dcd_state != p_priv->dcd_state) {
-               tty = tty_port_tty_get(&port->port);
-               if (tty && !C_CLOCAL(tty))
-                       tty_hangup(tty);
-               tty_kref_put(tty);
-       }
+       if (old_dcd_state != p_priv->dcd_state)
+               tty_port_tty_hangup(&port->port, true);
 
        /* Resubmit urb so we continue receiving */
        err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -510,7 +505,6 @@ static void usa28_instat_callback(struct urb *urb)
        struct usb_serial                       *serial;
        struct usb_serial_port                  *port;
        struct keyspan_port_private             *p_priv;
-       struct tty_struct                       *tty;
        int old_dcd_state;
        int status = urb->status;
 
@@ -551,12 +545,8 @@ static void        usa28_instat_callback(struct urb *urb)
        p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
        p_priv->ri_state = ((msg->ri) ? 1 : 0);
 
-       if (old_dcd_state != p_priv->dcd_state && old_dcd_state) {
-               tty = tty_port_tty_get(&port->port);
-               if (tty && !C_CLOCAL(tty))
-                       tty_hangup(tty);
-               tty_kref_put(tty);
-       }
+       if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
+               tty_port_tty_hangup(&port->port, true);
 
                /* Resubmit urb so we continue receiving */
        err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -642,12 +632,8 @@ static void        usa49_instat_callback(struct urb *urb)
        p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
        p_priv->ri_state = ((msg->ri) ? 1 : 0);
 
-       if (old_dcd_state != p_priv->dcd_state && old_dcd_state) {
-               struct tty_struct *tty = tty_port_tty_get(&port->port);
-               if (tty && !C_CLOCAL(tty))
-                       tty_hangup(tty);
-               tty_kref_put(tty);
-       }
+       if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
+               tty_port_tty_hangup(&port->port, true);
 
        /* Resubmit urb so we continue receiving */
        err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -851,7 +837,6 @@ static void usa90_instat_callback(struct urb *urb)
        struct usb_serial                       *serial;
        struct usb_serial_port                  *port;
        struct keyspan_port_private             *p_priv;
-       struct tty_struct                       *tty;
        int old_dcd_state, err;
        int status = urb->status;
 
@@ -880,12 +865,8 @@ static void        usa90_instat_callback(struct urb *urb)
        p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
        p_priv->ri_state = ((msg->ri) ? 1 : 0);
 
-       if (old_dcd_state != p_priv->dcd_state && old_dcd_state) {
-               tty = tty_port_tty_get(&port->port);
-               if (tty && !C_CLOCAL(tty))
-                       tty_hangup(tty);
-               tty_kref_put(tty);
-       }
+       if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
+               tty_port_tty_hangup(&port->port, true);
 
        /* Resubmit urb so we continue receiving */
        err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -953,12 +934,8 @@ static void        usa67_instat_callback(struct urb *urb)
        p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
        p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
 
-       if (old_dcd_state != p_priv->dcd_state && old_dcd_state) {
-               struct tty_struct *tty = tty_port_tty_get(&port->port);
-               if (tty && !C_CLOCAL(tty))
-                       tty_hangup(tty);
-               tty_kref_put(tty);
-       }
+       if (old_dcd_state != p_priv->dcd_state && old_dcd_state)
+               tty_port_tty_hangup(&port->port, true);
 
        /* Resubmit urb so we continue receiving */
        err = usb_submit_urb(urb, GFP_ATOMIC);
index f7d339d8187bd690b86b22ccf85b740781257226..602d1f389a3b6f48a8caa7d9979035f9a0233056 100644 (file)
@@ -1532,13 +1532,8 @@ static void option_instat_callback(struct urb *urb)
                        portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
                        portdata->ri_state = ((signals & 0x08) ? 1 : 0);
 
-                       if (old_dcd_state && !portdata->dcd_state) {
-                               struct tty_struct *tty =
-                                               tty_port_tty_get(&port->port);
-                               if (tty && !C_CLOCAL(tty))
-                                       tty_hangup(tty);
-                               tty_kref_put(tty);
-                       }
+                       if (old_dcd_state && !portdata->dcd_state)
+                               tty_port_tty_hangup(&port->port, true);
                } else {
                        dev_dbg(dev, "%s: type %x req %x\n", __func__,
                                req_pkt->bRequestType, req_pkt->bRequest);
index c13f6e747748b31d16c0d087fa4f8b1953826285..d66148a17fe36548e019c0b8b7b60aa563548a1a 100644 (file)
@@ -628,7 +628,6 @@ static void sierra_instat_callback(struct urb *urb)
                        unsigned char signals = *((unsigned char *)
                                        urb->transfer_buffer +
                                        sizeof(struct usb_ctrlrequest));
-                       struct tty_struct *tty;
 
                        dev_dbg(&port->dev, "%s: signal x%x\n", __func__,
                                signals);
@@ -639,11 +638,8 @@ static void sierra_instat_callback(struct urb *urb)
                        portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
                        portdata->ri_state = ((signals & 0x08) ? 1 : 0);
 
-                       tty = tty_port_tty_get(&port->port);
-                       if (tty && !C_CLOCAL(tty) &&
-                                       old_dcd_state && !portdata->dcd_state)
-                               tty_hangup(tty);
-                       tty_kref_put(tty);
+                       if (old_dcd_state && !portdata->dcd_state)
+                               tty_port_tty_hangup(&port->port, true);
                } else {
                        dev_dbg(&port->dev, "%s: type %x req %x\n",
                                __func__, req_pkt->bRequestType,
index b6e890a87eb1bae0640612548c1713fbae8b6186..d3548f87196828e1c3fb63e3838848148905c20e 100644 (file)
@@ -534,6 +534,7 @@ extern int tty_port_carrier_raised(struct tty_port *port);
 extern void tty_port_raise_dtr_rts(struct tty_port *port);
 extern void tty_port_lower_dtr_rts(struct tty_port *port);
 extern void tty_port_hangup(struct tty_port *port);
+extern void tty_port_tty_hangup(struct tty_port *port, bool check_clocal);
 extern void tty_port_tty_wakeup(struct tty_port *port);
 extern int tty_port_block_til_ready(struct tty_port *port,
                                struct tty_struct *tty, struct file *filp);
index edab393e0c82ec96bfd66dd662a888963761bab0..a2a508f5f2684e81ea69697e3e84ff69f2fe74da 100644 (file)
@@ -997,12 +997,8 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self,
                        self->settings.dce = IRCOMM_DELTA_CD;
                        ircomm_tty_check_modem_status(self);
                } else {
-                       struct tty_struct *tty = tty_port_tty_get(&self->port);
                        IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ );
-                       if (tty) {
-                               tty_hangup(tty);
-                               tty_kref_put(tty);
-                       }
+                       tty_port_tty_hangup(&self->port, false);
                }
                break;
        default: