Commit 95bef012 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

USB: more serial drivers writing after disconnect

this covers the rest of the obvious cases by using the flags
and locks to guard against disconnect which were introduced
in the earlier patch against mos7720.
Signed-off-by: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent e33fe4d8
...@@ -217,7 +217,10 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp) ...@@ -217,7 +217,10 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp)
priv->rts_state = 0; priv->rts_state = 0;
priv->dtr_state = 0; priv->dtr_state = 0;
airprime_send_setup(port); mutex_lock(&port->serial->disc_mutex);
if (!port->serial->disconnected)
airprime_send_setup(port);
mutex_lock(&port->serial->disc_mutex);
for (i = 0; i < NUM_READ_URBS; ++i) { for (i = 0; i < NUM_READ_URBS; ++i) {
usb_kill_urb (priv->read_urbp[i]); usb_kill_urb (priv->read_urbp[i]);
......
...@@ -348,7 +348,10 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp) ...@@ -348,7 +348,10 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp)
usb_kill_urb(port->write_urb); usb_kill_urb(port->write_urb);
usb_kill_urb(port->read_urb); usb_kill_urb(port->read_urb);
cp2101_set_config_single(port, CP2101_UART, UART_DISABLE); mutex_lock(&port->serial->disc_mutex);
if (!port->serial->disconnected)
cp2101_set_config_single(port, CP2101_UART, UART_DISABLE);
mutex_unlock(&port->serial->disc_mutex);
} }
/* /*
......
...@@ -1198,7 +1198,8 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) ...@@ -1198,7 +1198,8 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp)
dbg("%s", __FUNCTION__); dbg("%s", __FUNCTION__);
if (c_cflag & HUPCL){ mutex_lock(&port->serial->disc_mutex);
if (c_cflag & HUPCL && !port->serial->disconnected){
/* Disable flow control */ /* Disable flow control */
if (usb_control_msg(port->serial->dev, if (usb_control_msg(port->serial->dev,
usb_sndctrlpipe(port->serial->dev, 0), usb_sndctrlpipe(port->serial->dev, 0),
...@@ -1212,6 +1213,7 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) ...@@ -1212,6 +1213,7 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp)
/* drop RTS and DTR */ /* drop RTS and DTR */
clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
} /* Note change no line if hupcl is off */ } /* Note change no line if hupcl is off */
mutex_unlock(&port->serial->disc_mutex);
/* cancel any scheduled reading */ /* cancel any scheduled reading */
cancel_delayed_work(&priv->rx_work); cancel_delayed_work(&priv->rx_work);
......
...@@ -1020,19 +1020,26 @@ static void garmin_close (struct usb_serial_port *port, struct file * filp) ...@@ -1020,19 +1020,26 @@ static void garmin_close (struct usb_serial_port *port, struct file * filp)
if (!serial) if (!serial)
return; return;
garmin_clear(garmin_data_p); mutex_lock(&port->serial->disc_mutex);
if (!port->serial->disconnected)
garmin_clear(garmin_data_p);
/* shutdown our urbs */ /* shutdown our urbs */
usb_kill_urb (port->read_urb); usb_kill_urb (port->read_urb);
usb_kill_urb (port->write_urb); usb_kill_urb (port->write_urb);
if (noResponseFromAppLayer(garmin_data_p) || if (!port->serial->disconnected) {
((garmin_data_p->flags & CLEAR_HALT_REQUIRED) != 0)) { if (noResponseFromAppLayer(garmin_data_p) ||
process_resetdev_request(port); ((garmin_data_p->flags & CLEAR_HALT_REQUIRED) != 0)) {
garmin_data_p->state = STATE_RESET; process_resetdev_request(port);
garmin_data_p->state = STATE_RESET;
} else {
garmin_data_p->state = STATE_DISCONNECTED;
}
} else { } else {
garmin_data_p->state = STATE_DISCONNECTED; garmin_data_p->state = STATE_DISCONNECTED;
} }
mutex_unlock(&port->serial->disc_mutex);
} }
......
...@@ -362,7 +362,7 @@ static void visor_close (struct usb_serial_port *port, struct file * filp) ...@@ -362,7 +362,7 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
kfree (transfer_buffer); kfree (transfer_buffer);
} }
} }
mutex_lock(&port->serial->disc_mutex); mutex_unlock(&port->serial->disc_mutex);
if (stats) if (stats)
dev_info(&port->dev, "Bytes In = %d Bytes Out = %d\n", dev_info(&port->dev, "Bytes In = %d Bytes Out = %d\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment