TTY: hso, use tty from tty_port
authorJiri Slaby <jslaby@suse.cz>
Mon, 2 Apr 2012 11:54:07 +0000 (13:54 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Apr 2012 18:18:36 +0000 (11:18 -0700)
We switched tty refcounting there to the one provided by tty_port
helpers. So tty_port->tty is now protected by tty_port->lock, not by
hso_serial->serial_lock.

Side note: tty->driver_data does not need the lock, so it is needed
neither in open, nor in close paths.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Jan Dumon <j.dumon@option.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/usb/hso.c

index ec782c7eabd86667a1e6294bcb6e9cc69c3da862..813d70946d3979e7778e532e105095eac2643553 100644 (file)
@@ -250,7 +250,6 @@ struct hso_serial {
 
        struct tty_port port;
        /* from usb_serial_port */
-       struct tty_struct *tty;
        spinlock_t serial_lock;
 
        int (*write_data) (struct hso_serial *serial);
@@ -1297,11 +1296,8 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
        kref_get(&serial->parent->ref);
 
        /* setup */
-       spin_lock_irq(&serial->serial_lock);
        tty->driver_data = serial;
-       tty_kref_put(serial->tty);
-       serial->tty = tty_kref_get(tty);
-       spin_unlock_irq(&serial->serial_lock);
+       tty_port_tty_set(&serial->port, tty);
 
        /* check for port already opened, if not set the termios */
        serial->port.count++;
@@ -1358,13 +1354,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
 
        if (serial->port.count <= 0) {
                serial->port.count = 0;
-               spin_lock_irq(&serial->serial_lock);
-               if (serial->tty == tty) {
-                       serial->tty->driver_data = NULL;
-                       serial->tty = NULL;
-                       tty_kref_put(tty);
-               }
-               spin_unlock_irq(&serial->serial_lock);
+               tty_port_tty_set(&serial->port, NULL);
                if (!usb_gone)
                        hso_stop_serial_device(serial->parent);
                tasklet_kill(&serial->unthrottle_tasklet);
@@ -1947,14 +1937,13 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb)
 
        spin_lock(&serial->serial_lock);
        serial->tx_urb_used = 0;
-       tty = tty_kref_get(serial->tty);
        spin_unlock(&serial->serial_lock);
        if (status) {
                handle_usb_error(status, __func__, serial->parent);
-               tty_kref_put(tty);
                return;
        }
        hso_put_activity(serial->parent);
+       tty = tty_port_tty_get(&serial->port);
        if (tty) {
                tty_wakeup(tty);
                tty_kref_put(tty);
@@ -1994,7 +1983,6 @@ static void ctrl_callback(struct urb *urb)
        struct hso_serial *serial = urb->context;
        struct usb_ctrlrequest *req;
        int status = urb->status;
-       struct tty_struct *tty;
 
        /* sanity check */
        if (!serial)
@@ -2002,11 +1990,9 @@ static void ctrl_callback(struct urb *urb)
 
        spin_lock(&serial->serial_lock);
        serial->tx_urb_used = 0;
-       tty = tty_kref_get(serial->tty);
        spin_unlock(&serial->serial_lock);
        if (status) {
                handle_usb_error(status, __func__, serial->parent);
-               tty_kref_put(tty);
                return;
        }
 
@@ -2024,13 +2010,15 @@ static void ctrl_callback(struct urb *urb)
                put_rxbuf_data_and_resubmit_ctrl_urb(serial);
                spin_unlock(&serial->serial_lock);
        } else {
+               struct tty_struct *tty = tty_port_tty_get(&serial->port);
                hso_put_activity(serial->parent);
-               if (tty)
+               if (tty) {
                        tty_wakeup(tty);
+                       tty_kref_put(tty);
+               }
                /* response to a write command */
                hso_kick_transmit(serial);
        }
-       tty_kref_put(tty);
 }
 
 /* handle RX data for serial port */
@@ -2046,8 +2034,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
                return -2;
        }
 
-       /* All callers to put_rxbuf_data hold serial_lock */
-       tty = tty_kref_get(serial->tty);
+       tty = tty_port_tty_get(&serial->port);
 
        /* Push data to tty */
        if (tty) {
@@ -2067,12 +2054,12 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
                        write_length_remaining -= curr_write_len;
                        tty_flip_buffer_push(tty);
                }
+               tty_kref_put(tty);
        }
        if (write_length_remaining == 0) {
                serial->curr_rx_urb_offset = 0;
                serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
        }
-       tty_kref_put(tty);
        return write_length_remaining;
 }
 
@@ -3166,13 +3153,12 @@ static void hso_free_interface(struct usb_interface *interface)
                if (serial_table[i] &&
                    (serial_table[i]->interface == interface)) {
                        hso_dev = dev2ser(serial_table[i]);
-                       spin_lock_irq(&hso_dev->serial_lock);
-                       tty = tty_kref_get(hso_dev->tty);
-                       spin_unlock_irq(&hso_dev->serial_lock);
-                       if (tty)
+                       tty = tty_port_tty_get(&hso_dev->port);
+                       if (tty) {
                                tty_hangup(tty);
+                               tty_kref_put(tty);
+                       }
                        mutex_lock(&hso_dev->parent->mutex);
-                       tty_kref_put(tty);
                        hso_dev->parent->usb_gone = 1;
                        mutex_unlock(&hso_dev->parent->mutex);
                        kref_put(&serial_table[i]->ref, hso_serial_ref_free);