# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.571   -> 1.572  
#       drivers/usb/serial/usbserial.c  1.28    -> 1.29   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/03/28      [EMAIL PROTECTED]      1.572
# USB serial core
# 
# Module count of a serial converter driver is currently not
# decremented if a disconnect happens while the tty is held open.
# The fix is to close the device in usb_serial_disconnect() so that
# module refcounts are properly updated.
# --------------------------------------------
#
diff -Nru a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c
--- a/drivers/usb/serial/usbserial.c    Wed Apr  3 16:39:19 2002
+++ b/drivers/usb/serial/usbserial.c    Wed Apr  3 16:39:19 2002
@@ -576,43 +576,45 @@
        return retval;
 }
 
-static void serial_close(struct tty_struct *tty, struct file * filp)
+static void __serial_close(struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
-       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
-
-       if (!serial)
-               return;
-
-       down (&port->sem);
-
-       dbg(__FUNCTION__ " - port %d", port->number);
-
-       if (tty->driver_data == NULL) {
-               /* disconnect beat us to the punch here, so handle it gracefully */
-               goto exit;
-       }
        if (!port->open_count) {
                dbg (__FUNCTION__ " - port not opened");
-               goto exit_no_mod_dec;
+               return;
        }
 
        --port->open_count;
        if (port->open_count <= 0) {
                /* only call the device specific close if this 
                 * port is being closed by the last owner */
-               if (serial->type->close)
-                       serial->type->close(port, filp);
+               if (port->serial->type->close)
+                       port->serial->type->close(port, filp);
                else
                        generic_close(port, filp);
                port->open_count = 0;
        }
 
-exit:
-       if (serial->type->owner)
-               __MOD_DEC_USE_COUNT(serial->type->owner);
+       if (port->serial->type->owner)
+               __MOD_DEC_USE_COUNT(port->serial->type->owner);
+}
+
+static void serial_close(struct tty_struct *tty, struct file * filp)
+{
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+
+       if (!serial)
+               return;
+
+       down (&port->sem);
+
+       dbg(__FUNCTION__ " - port %d", port->number);
+
+       /* if disconnect beat us to the punch here, there's nothing to do */
+       if (tty->driver_data) {
+               __serial_close(port, filp);
+       }
 
-exit_no_mod_dec:
        up (&port->sem);
 }
 
@@ -1400,10 +1402,15 @@
        if (serial) {
                /* fail all future close/read/write/ioctl/etc calls */
                for (i = 0; i < serial->num_ports; ++i) {
-                       down (&serial->port[i].sem);
-                       if (serial->port[i].tty != NULL)
-                               serial->port[i].tty->driver_data = NULL;
-                       up (&serial->port[i].sem);
+                       port = &serial->port[i];
+                       down (&port->sem);
+                       if (port->tty != NULL) {
+                               while (port->open_count > 0) {
+                                       __serial_close(port, NULL);
+                               }
+                               port->tty->driver_data = NULL;
+                       }
+                       up (&port->sem);
                }
 
                serial->dev = NULL;

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to