From: Oliver Neukum Date: Tue, 22 Jan 2008 12:56:18 +0000 (+0100) Subject: USB: more serial drivers writing after disconnect X-Git-Tag: v2.6.25-rc1~1075^2~20 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=95bef012ea4a3cce437a4fcf59bb097d14944b0d;p=linux-2.6 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: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 77bb893bf2..f156dba030 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -217,7 +217,10 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp) priv->rts_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) { usb_kill_urb (priv->read_urbp[i]); diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index cd5f71b7f6..f3ca66017a 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -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->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); } /* diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 2c142bb04f..90dcc625f7 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1198,7 +1198,8 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) dbg("%s", __FUNCTION__); - if (c_cflag & HUPCL){ + mutex_lock(&port->serial->disc_mutex); + if (c_cflag & HUPCL && !port->serial->disconnected){ /* Disable flow control */ if (usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), @@ -1212,6 +1213,7 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) /* drop RTS and DTR */ clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); } /* Note change no line if hupcl is off */ + mutex_unlock(&port->serial->disc_mutex); /* cancel any scheduled reading */ cancel_delayed_work(&priv->rx_work); diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index f1c90cfe72..d74e43d692 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1020,19 +1020,26 @@ static void garmin_close (struct usb_serial_port *port, struct file * filp) if (!serial) return; - garmin_clear(garmin_data_p); + mutex_lock(&port->serial->disc_mutex); + if (!port->serial->disconnected) + garmin_clear(garmin_data_p); /* shutdown our urbs */ usb_kill_urb (port->read_urb); usb_kill_urb (port->write_urb); - if (noResponseFromAppLayer(garmin_data_p) || - ((garmin_data_p->flags & CLEAR_HALT_REQUIRED) != 0)) { - process_resetdev_request(port); - garmin_data_p->state = STATE_RESET; + if (!port->serial->disconnected) { + if (noResponseFromAppLayer(garmin_data_p) || + ((garmin_data_p->flags & CLEAR_HALT_REQUIRED) != 0)) { + process_resetdev_request(port); + garmin_data_p->state = STATE_RESET; + } else { + garmin_data_p->state = STATE_DISCONNECTED; + } } else { garmin_data_p->state = STATE_DISCONNECTED; } + mutex_unlock(&port->serial->disc_mutex); } diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index c2347995c7..22b3f78a38 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -362,7 +362,7 @@ static void visor_close (struct usb_serial_port *port, struct file * filp) kfree (transfer_buffer); } } - mutex_lock(&port->serial->disc_mutex); + mutex_unlock(&port->serial->disc_mutex); if (stats) dev_info(&port->dev, "Bytes In = %d Bytes Out = %d\n",