USB: more serial drivers writing after disconnect
authorOliver Neukum <oliver@neukum.org>
Tue, 22 Jan 2008 12:56:18 +0000 (13:56 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 1 Feb 2008 22:35:05 +0000 (14:35 -0800)
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 <oneukum@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/serial/airprime.c
drivers/usb/serial/cp2101.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/garmin_gps.c
drivers/usb/serial/visor.c

index 77bb893bf2e922c51bb51ef4e2ac69f6d2cd2a86..f156dba0300f77168f7774199e988074bd249e8a 100644 (file)
@@ -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]);
index cd5f71b7f6372b251967c317f8829450e508c912..f3ca66017a031ba81db256216b905b4cf3989efa 100644 (file)
@@ -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);
 }
 
 /*
index 2c142bb04fe17256616de04d07891a4ad27fea5f..90dcc625f70deb008c45ca0c6c349ba0a6d6eb4e 100644 (file)
@@ -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);
index f1c90cfe72515365236c9ddf61e1c41ee90fe82a..d74e43d69230b5ea1d7b75a4b599f9052f658004 100644 (file)
@@ -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);
 }
 
 
index c2347995c786e7224e18fb784bd2c4327ad7d610..22b3f78a388ce0d40486ede8c98f9af41051dc49 100644 (file)
@@ -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",