Skip to content

Commit

Permalink
USB: io_ti: fix abuse of interface data
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Johan Hovold authored and Greg Kroah-Hartman committed Apr 10, 2012
1 parent 5c0c758 commit af58105
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions drivers/usb/serial/io_ti.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
Expand All @@ -578,15 +579,15 @@ 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;
msleep(10);
}

/* disconnected */
if (!usb_get_intfdata(port->port->serial->interface))
if (serial->disconnected)
return;

/* wait one more character time, based on baud rate */
Expand Down Expand Up @@ -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);

Expand All @@ -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) {
Expand Down

0 comments on commit af58105

Please sign in to comment.