If disconnect() is called for a logical disconnect, no more IO must be
done after disconnect() returns, or the old and new drivers may conflict.
This patch avoids this by using the flag and lock introduced by the earlier
patch for the mos7720 driver.

Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>

2.6.25 material.

        Regards
                Oliver

----

--- linux-2.6.24-serial_intfdata/drivers/usb/serial/whiteheat.c.alt     
2008-01-21 15:12:38.000000000 +0100
+++ linux-2.6.24-serial_intfdata/drivers/usb/serial/whiteheat.c 2008-01-21 
15:12:45.000000000 +0100
@@ -659,11 +659,14 @@ static void whiteheat_close(struct usb_s
        struct list_head *tmp2;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
-       
+
+       mutex_lock(&port->serial->disc_mutex);
        /* filp is NULL when called from usb_serial_disconnect */
-       if (filp && (tty_hung_up_p(filp))) {
+       if ((filp && (tty_hung_up_p(filp))) || port->serial->disconnected) {
+               mutex_unlock(&port->serial->disc_mutex);
                return;
        }
+       mutex_unlock(&port->serial->disc_mutex);
 
        port->tty->closing = 1;
 
--- linux-2.6.24-serial_intfdata/drivers/usb/serial/mct_u232.c.alt      
2008-01-21 16:43:21.000000000 +0100
+++ linux-2.6.24-serial_intfdata/drivers/usb/serial/mct_u232.c  2008-01-21 
16:43:38.000000000 +0100
@@ -482,21 +482,22 @@ error:
 static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
 {
        unsigned int c_cflag;
-       unsigned long flags;
        unsigned int control_state;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
        dbg("%s port %d", __FUNCTION__, port->number);
 
        if (port->tty) {
                c_cflag = port->tty->termios->c_cflag;
-               if (c_cflag & HUPCL) {
-                  /* drop DTR and RTS */
-                  spin_lock_irqsave(&priv->lock, flags);
-                  priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
-                  control_state = priv->control_state;
-                  spin_unlock_irqrestore(&priv->lock, flags);
-                  mct_u232_set_modem_ctrl(port->serial, control_state);
+               mutex_lock(&port->serial->disc_mutex);
+               if (c_cflag & HUPCL && !port->serial->disconnected) {
+                       /* drop DTR and RTS */
+                       spin_lock_irq(&priv->lock);
+                       priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
+                       control_state = priv->control_state;
+                       spin_unlock_irq(&priv->lock);
+                       mct_u232_set_modem_ctrl(port->serial, control_state);
                }
+               mutex_unlock(&port->serial->disc_mutex);
        }
 
 
--- linux-2.6.24-serial_intfdata/drivers/usb/serial/option.c.alt        
2008-01-21 16:38:44.000000000 +0100
+++ linux-2.6.24-serial_intfdata/drivers/usb/serial/option.c    2008-01-21 
16:38:53.000000000 +0100
@@ -640,7 +640,10 @@ static void option_close(struct usb_seri
        portdata->dtr_state = 0;
 
        if (serial->dev) {
-               option_send_setup(port);
+               mutex_lock(&serial->disc_mutex);
+               if (!serial->disconnected)
+                       option_send_setup(port);
+               mutex_unlock(&serial->disc_mutex);
 
                /* Stop reading/writing urbs */
                for (i = 0; i < N_IN_URB; i++)
--- linux-2.6.24-serial_intfdata/drivers/usb/serial/sierra.c.alt        
2008-01-21 15:50:45.000000000 +0100
+++ linux-2.6.24-serial_intfdata/drivers/usb/serial/sierra.c    2008-01-21 
15:50:50.000000000 +0100
@@ -561,7 +561,10 @@ static void sierra_close(struct usb_seri
        portdata->dtr_state = 0;
 
        if (serial->dev) {
-               sierra_send_setup(port);
+               mutex_lock(&serial->disc_mutex);
+               if (!serial->disconnected)
+                       sierra_send_setup(port);
+               mutex_unlock(&serial->disc_mutex);
 
                /* Stop reading/writing urbs */
                for (i = 0; i < N_IN_URB; i++)
--- linux-2.6.24-serial_intfdata/drivers/usb/serial/visor.c.alt 2008-01-21 
15:21:03.000000000 +0100
+++ linux-2.6.24-serial_intfdata/drivers/usb/serial/visor.c     2008-01-21 
15:21:09.000000000 +0100
@@ -349,16 +349,20 @@ static void visor_close (struct usb_seri
        usb_kill_urb(port->read_urb);
        usb_kill_urb(port->interrupt_in_urb);
 
-       /* Try to send shutdown message, if the device is gone, this will just 
fail. */
-       transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
-       if (transfer_buffer) {
-               usb_control_msg (port->serial->dev,
-                                usb_rcvctrlpipe(port->serial->dev, 0),
-                                VISOR_CLOSE_NOTIFICATION, 0xc2,
-                                0x0000, 0x0000, 
-                                transfer_buffer, 0x12, 300);
-               kfree (transfer_buffer);
+       mutex_lock(&port->serial->disc_mutex);
+       if (!port->serial->disconnected) {
+               /* Try to send shutdown message, unless the device is gone */
+               transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
+               if (transfer_buffer) {
+                       usb_control_msg (port->serial->dev,
+                                        usb_rcvctrlpipe(port->serial->dev, 0),
+                                        VISOR_CLOSE_NOTIFICATION, 0xc2,
+                                        0x0000, 0x0000, 
+                                        transfer_buffer, 0x12, 300);
+                       kfree (transfer_buffer);
+               }
        }
+       mutex_lock(&port->serial->disc_mutex);
 
        if (stats)
                dev_info(&port->dev, "Bytes In = %d  Bytes Out = %d\n",
-
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to