From b58c07f078c24472ba1e1a0bad9b6a4f404d9864 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 22 Jan 2008 13:56:18 +0100 Subject: [PATCH] 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 --- drivers/usb/serial/airprime.c | 5 ++++- drivers/usb/serial/cp2101.c | 5 ++++- drivers/usb/serial/ftdi_sio.c | 4 +++- drivers/usb/serial/garmin_gps.c | 17 ++++++++++++----- drivers/usb/serial/visor.c | 2 +- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 77bb893bf2e92..f156dba0300f7 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 cd5f71b7f6372..f3ca66017a031 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 2c142bb04fe17..90dcc625f70de 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 f1c90cfe72515..d74e43d69230b 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 c2347995c786e..22b3f78a388ce 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", -- 2.39.5