Hi,

the mos7720 driver sends two commands to the device whenever it is
closed. It does so unconditionally even if the device has been disconnected.
It seems to me that this is wrong. Making sure that this does not happen
for disconnected devices takes a bit of infrastructure in the generic part.
However I am not sure whether this interfeeres with hanging up the tty.
What do you think?

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

        Regards
                Oliver

----

--- linux-2.6.24-rc5-vanilla/include/linux/usb/serial.h 2007-12-20 
13:14:04.000000000 +0100
+++ linux-2.6.24-rc5-work/include/linux/usb/serial.h    2007-12-20 
12:39:40.000000000 +0100
@@ -128,6 +128,7 @@ struct usb_serial {
        struct usb_device *             dev;
        struct usb_serial_driver *      type;
        struct usb_interface *          interface;
+       unsigned char                   disconnected;
        unsigned char                   minor;
        unsigned char                   num_ports;
        unsigned char                   num_port_pointers;
@@ -137,6 +138,7 @@ struct usb_serial {
        char                            num_bulk_out;
        struct usb_serial_port *        port[MAX_NUM_PORTS];
        struct kref                     kref;
+       struct mutex                    disc_mutex;
        void *                          private;
 };
 #define to_usb_serial(d) container_of(d, struct usb_serial, kref)
--- linux-2.6.24-rc5-vanilla/drivers/usb/serial/usb-serial.c    2007-12-20 
13:13:53.000000000 +0100
+++ linux-2.6.24-rc5-work/drivers/usb/serial/usb-serial.c       2007-12-20 
12:45:00.000000000 +0100
@@ -625,6 +625,7 @@ static struct usb_serial * create_serial
        serial->type = driver;
        serial->interface = interface;
        kref_init(&serial->kref);
+       mutex_init(&serial->disc_mutex);
 
        return serial;
 }
@@ -1080,20 +1081,22 @@ void usb_serial_disconnect(struct usb_in
        usb_serial_console_disconnect(serial);
        dbg ("%s", __FUNCTION__);
 
+       mutex_lock(&serial->disc_mutex);
        usb_set_intfdata (interface, NULL);
-       if (serial) {
-               for (i = 0; i < serial->num_ports; ++i) {
-                       port = serial->port[i];
-                       if (port) {
-                               if (port->tty)
-                                       tty_hangup(port->tty);
-                               kill_traffic(port);
-                       }
+       /* must use extra flag, as intfdata can be reset */
+       serial->disconnected = 1;
+       for (i = 0; i < serial->num_ports; ++i) {
+               port = serial->port[i];
+               if (port) {
+                       if (port->tty)
+                               tty_hangup(port->tty);
+                       kill_traffic(port);
                }
-               /* let the last holder of this object 
-                * cause it to be cleaned up */
-               usb_serial_put(serial);
        }
+       /* let the last holder of this object 
+        * cause it to be cleaned up */
+       mutex_unlock(&serial->disc_mutex);
+       usb_serial_put(serial);
        dev_info(dev, "device disconnected\n");
 }
 
--- linux-2.6.24-rc5-vanilla/drivers/usb/serial/mos7720.c       2007-12-20 
13:13:53.000000000 +0100
+++ linux-2.6.24-rc5-work/drivers/usb/serial/mos7720.c  2007-12-20 
12:39:36.000000000 +0100
@@ -564,22 +564,25 @@ static void mos7720_close(struct usb_ser
        }
 
        /* While closing port, shutdown all bulk read, write  *
-        * and interrupt read if they exists                  */
-       if (serial->dev) {
-               dbg("Shutdown bulk write");
-               usb_kill_urb(port->write_urb);
-               dbg("Shutdown bulk read");
-               usb_kill_urb(port->read_urb);
+        * and interrupt read if they exists, otherwise nop   */
+       dbg("Shutdown bulk write");
+       usb_kill_urb(port->write_urb);
+       dbg("Shutdown bulk read");
+       usb_kill_urb(port->read_urb);
+
+       mutex_lock(&serial->disc_mutex);
+       /* these commands must not be issued if the device has
+        * been disconnected */
+       if (!serial->disconnected) {
+               data = 0x00;
+               send_mos_cmd(serial, MOS_WRITE, port->number - 
port->serial->minor,
+                            0x04, &data);
+
+               data = 0x00;
+               send_mos_cmd(serial, MOS_WRITE, port->number - 
port->serial->minor,
+                            0x01, &data);
        }
-
-       data = 0x00;
-       send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
-                    0x04, &data);
-
-       data = 0x00;
-       send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
-                    0x01, &data);
-
+       mutex_unlock(&serial->disc_mutex);
        mos7720_port->open = 0;
 
        dbg("Leaving %s", __FUNCTION__);
-
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