diff options
author | Johan Hovold <jhovold@gmail.com> | 2012-03-26 20:31:38 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-04-10 22:32:54 +0200 |
commit | af5810597ab38ed1eb1d38e04b6e89c9ccec988e (patch) | |
tree | d7cd258198d9f91a152b929aa957865431b65457 | |
parent | USB: whiteheat: reimplement using generic framework (diff) | |
download | linux-af5810597ab38ed1eb1d38e04b6e89c9ccec988e.tar.xz linux-af5810597ab38ed1eb1d38e04b6e89c9ccec988e.zip |
USB: io_ti: fix abuse of interface data
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>
-rw-r--r-- | drivers/usb/serial/io_ti.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 40a95a7fe383..5e4b47194819 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -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) { |