USB: io_ti: fix abuse of interface data
authorJohan Hovold <jhovold@gmail.com>
Mon, 26 Mar 2012 18:31:38 +0000 (20:31 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Apr 2012 20:32:54 +0000 (13:32 -0700)
Fix abuse of interface data which was used to signal device disconnect.

Use the usb_serial disconnect flag and mutex where appropriate.

Note that there's no need to grab the mutex in chase_port as it does not
access the device.

Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/serial/io_ti.c

index 40a95a7fe3837b04aa629eb9d1376799d9e71fc9..5e4b47194819e0326579e9753a70c8d61c1a30ba 100644 (file)
@@ -547,6 +547,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
 {
        int baud_rate;
        struct tty_struct *tty = tty_port_tty_get(&port->port->port);
+       struct usb_serial *serial = port->port->serial;
        wait_queue_t wait;
        unsigned long flags;
 
@@ -561,7 +562,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
                set_current_state(TASK_INTERRUPTIBLE);
                if (kfifo_len(&port->write_fifo) == 0
                || timeout == 0 || signal_pending(current)
-               || !usb_get_intfdata(port->port->serial->interface))
+               || serial->disconnected)
                        /* disconnect */
                        break;
                spin_unlock_irqrestore(&port->ep_lock, flags);
@@ -578,7 +579,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
        /* wait for data to drain from the device */
        timeout += jiffies;
        while ((long)(jiffies - timeout) < 0 && !signal_pending(current)
-       && usb_get_intfdata(port->port->serial->interface)) {
+                                               && !serial->disconnected) {
                /* not disconnected */
                if (!tx_active(port))
                        break;
@@ -586,7 +587,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
        }
 
        /* disconnected */
-       if (!usb_get_intfdata(port->port->serial->interface))
+       if (serial->disconnected)
                return;
 
        /* wait one more character time, based on baud rate */
@@ -2003,8 +2004,8 @@ static void edge_close(struct usb_serial_port *port)
 {
        struct edgeport_serial *edge_serial;
        struct edgeport_port *edge_port;
+       struct usb_serial *serial = port->serial;
        int port_number;
-       int status;
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -2028,12 +2029,18 @@ static void edge_close(struct usb_serial_port *port)
         * send a close port command to it */
        dbg("%s - send umpc_close_port", __func__);
        port_number = port->number - port->serial->minor;
-       status = send_cmd(port->serial->dev,
+
+       mutex_lock(&serial->disc_mutex);
+       if (!serial->disconnected) {
+               send_cmd(serial->dev,
                                     UMPC_CLOSE_PORT,
                                     (__u8)(UMPM_UART1_PORT + port_number),
                                     0,
                                     NULL,
                                     0);
+       }
+       mutex_unlock(&serial->disc_mutex);
+
        mutex_lock(&edge_serial->es_lock);
        --edge_port->edge_serial->num_ports_open;
        if (edge_port->edge_serial->num_ports_open <= 0) {