# 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.554   -> 1.555  
#       drivers/usb/serial/usbserial.c  1.26    -> 1.27   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/03/21      [EMAIL PROTECTED]  1.555
# USB serial driver core
# 
# - Moved all manipulation of port->open_count into the core.  Now the
#   individual driver's open and close functions are called only when the
#   first open() and last close() is called.  Making the drivers a bit
#   smaller and simpler.
# - Fixed a bug if a driver didn't have the owner field set.
# --------------------------------------------
#
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:51 2002
+++ b/drivers/usb/serial/usbserial.c    Wed Apr  3 16:39:51 2002
@@ -15,6 +15,13 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * (03/21/2002) gkh
+ *     Moved all manipulation of port->open_count into the core.  Now the
+ *     individual driver's open and close functions are called only when the
+ *     first open() and last close() is called.  Making the drivers a bit
+ *     smaller and simpler.
+ *     Fixed a bug if a driver didn't have the owner field set.
+ *
  * (02/26/2002) gkh
  *     Moved all locking into the main serial_* functions, instead of having 
  *     the individual drivers have to grab the port semaphore.  This should
@@ -500,7 +507,7 @@
        struct usb_serial *serial;
        struct usb_serial_port *port;
        unsigned int portNumber;
-       int retval;
+       int retval = 0;
        
        dbg(__FUNCTION__);
 
@@ -525,14 +532,21 @@
        if (serial->type->owner)
                __MOD_INC_USE_COUNT(serial->type->owner);
 
-       /* pass on to the driver specific version of this function if it is available 
*/
-       if (serial->type->open)
-               retval = serial->type->open(port, filp);
-       else
-               retval = generic_open(port, filp);
+       ++port->open_count;
+       if (port->open_count == 1) {
+               /* only call the device specific open if this 
+                * is the first time the port is opened */
+               if (serial->type->open)
+                       retval = serial->type->open(port, filp);
+               else
+                       retval = generic_open(port, filp);
+       }
 
-       if (retval)
-               __MOD_DEC_USE_COUNT(serial->type->owner);
+       if (retval) {
+               port->open_count = 0;
+               if (serial->type->owner)
+                       __MOD_DEC_USE_COUNT(serial->type->owner);
+       }
 
        up (&port->sem);
        return retval;
@@ -559,11 +573,16 @@
                goto exit_no_mod_dec;
        }
 
-       /* pass on to the driver specific version of this function if it is available 
*/
-       if (serial->type->close)
-               serial->type->close(port, filp);
-       else
-               generic_close(port, filp);
+       --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);
+               else
+                       generic_close(port, filp);
+               port->open_count = 0;
+       }
 
 exit:
        if (serial->type->owner)
@@ -791,6 +810,8 @@
 
 static void serial_shutdown (struct usb_serial *serial)
 {
+       dbg(__FUNCTION__);
+
        if (serial->type->shutdown)
                serial->type->shutdown(serial);
        else
@@ -810,54 +831,51 @@
 
        dbg(__FUNCTION__ " - port %d", port->number);
 
-       ++port->open_count;
-
-       if (port->open_count == 1) {
-               /* force low_latency on so that our tty_push actually forces the data 
through, 
-                  otherwise it is scheduled, and with high data rates (like with 
OHCI) data
-                  can get lost. */
-               port->tty->low_latency = 1;
-
-               /* if we have a bulk interrupt, start reading from it */
-               if (serial->num_bulk_in) {
-                       /* Start reading from the device */
-                       usb_fill_bulk_urb (port->read_urb, serial->dev,
-                                          usb_rcvbulkpipe(serial->dev, 
port->bulk_in_endpointAddress),
-                                          port->read_urb->transfer_buffer,
-                                          port->read_urb->transfer_buffer_length,
-                                          ((serial->type->read_bulk_callback) ?
-                                            serial->type->read_bulk_callback :
-                                            generic_read_bulk_callback),
-                                          port);
-                       result = usb_submit_urb(port->read_urb, GFP_KERNEL);
-                       if (result)
-                               err(__FUNCTION__ " - failed resubmitting read urb, 
error %d", result);
-               }
+       /* force low_latency on so that our tty_push actually forces the data through, 
+          otherwise it is scheduled, and with high data rates (like with OHCI) data
+          can get lost. */
+       port->tty->low_latency = 1;
+
+       /* if we have a bulk interrupt, start reading from it */
+       if (serial->num_bulk_in) {
+               /* Start reading from the device */
+               usb_fill_bulk_urb (port->read_urb, serial->dev,
+                                  usb_rcvbulkpipe(serial->dev, 
+port->bulk_in_endpointAddress),
+                                  port->read_urb->transfer_buffer,
+                                  port->read_urb->transfer_buffer_length,
+                                  ((serial->type->read_bulk_callback) ?
+                                    serial->type->read_bulk_callback :
+                                    generic_read_bulk_callback),
+                                  port);
+               result = usb_submit_urb(port->read_urb, GFP_KERNEL);
+               if (result)
+                       err(__FUNCTION__ " - failed resubmitting read urb, error %d", 
+result);
        }
 
        return result;
 }
 
-static void generic_close (struct usb_serial_port *port, struct file * filp)
+static void generic_cleanup (struct usb_serial_port *port)
 {
        struct usb_serial *serial = port->serial;
 
        dbg(__FUNCTION__ " - port %d", port->number);
 
-       --port->open_count;
-
-       if (port->open_count <= 0) {
-               if (serial->dev) {
-                       /* shutdown any bulk reads that might be going on */
-                       if (serial->num_bulk_out)
-                               usb_unlink_urb (port->write_urb);
-                       if (serial->num_bulk_in)
-                               usb_unlink_urb (port->read_urb);
-               }
-               port->open_count = 0;
+       if (serial->dev) {
+               /* shutdown any bulk reads that might be going on */
+               if (serial->num_bulk_out)
+                       usb_unlink_urb (port->write_urb);
+               if (serial->num_bulk_in)
+                       usb_unlink_urb (port->read_urb);
        }
 }
 
+static void generic_close (struct usb_serial_port *port, struct file * filp)
+{
+       dbg(__FUNCTION__ " - port %d", port->number);
+       generic_cleanup (port);
+}
+
 static int generic_write (struct usb_serial_port *port, int from_user, const unsigned 
char *buf, int count)
 {
        struct usb_serial *serial = port->serial;
@@ -1025,10 +1043,7 @@
 
        /* stop reads and writes on all ports */
        for (i=0; i < serial->num_ports; ++i) {
-               down (&serial->port[i].sem);
-               while (serial->port[i].open_count > 0)
-                       generic_close (&serial->port[i], NULL);
-               up (&serial->port[i].sem);
+               generic_cleanup (&serial->port[i]);
        }
 }
 
@@ -1040,11 +1055,13 @@
 
        dbg(__FUNCTION__ " - port %d", port->number);
        
-       if (!serial) {
+       if (!serial)
                return;
-       }
 
        tty = port->tty;
+       if (!tty)
+               return;
+
        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) {
                dbg(__FUNCTION__ " - write wakeup call.");
                (tty->ldisc.write_wakeup)(tty);
@@ -1334,6 +1351,7 @@
        struct usb_serial_port *port;
        int i;
 
+       dbg(__FUNCTION__);
        if (serial) {
                /* fail all future close/read/write/ioctl/etc calls */
                for (i = 0; i < serial->num_ports; ++i) {

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

Reply via email to