Hi,

Here's a patch against 2.5.7 that moves the open_count logic into the
usbserial.c file.  Now the individual usb-serial drivers do not need to
check this value in their open and close functions.  The individual
driver's open and close functions will only get called on the first
open() and last close() call a user does on the tty port.  This removes
logic that every driver had to implement.

This is the patch for the usbserial.c core.  A patch for all of the
usb-serial drivers will be in the next message.

thanks,

greg k-h


# This is a BitKeeper generated patch for the following project:
# Project Name: greg k-h's linux 2.5 USB kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.409   -> 1.410  
#       drivers/usb/serial/usbserial.c  1.23    -> 1.24   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/03/21      [EMAIL PROTECTED]  1.410
# 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    Thu Mar 21 16:22:13 2002
+++ b/drivers/usb/serial/usbserial.c    Thu Mar 21 16:22:13 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