On Sat, 17 Jun 2006 22:09:49 -0300, "Luiz Fernando N. Capitulino" <[EMAIL 
PROTECTED]> wrote:

> | Greg, does this look sane to you?

>   1. While you're are at it, please, create a new function to kill
>      'port', because now the code in port_release() and destroy_serial()
>      does exactly the same thing (to kill 'port').
> 
>   2. Just to be safe, do a 'port = NULL' after the call to kfree()

So, I refactored it according to #1, but I'd rather have you send me
a patch which implements #2. It just makes no sense to me, I cannot
understand what you could possibly want here.

I allso threw in the patch for visor leaks. I sent it to Greg before,
but typoed the list name at cc:

-- Pete

P.S. Greg was up to his neck in FreedomHEC activities, as I gather from
his blog, and it was unfortunate. Linus released 2.6.17 today... We better
hurry with the agreement about this patch of we miss the merge window.
Send me counter-patches if any.

diff -urp -X dontdiff 
linux-2.6.17-rc6-git7-gregkh/drivers/usb/serial/usb-serial.c 
linux-2.6.17-rc6-git7-gregkh-v/drivers/usb/serial/usb-serial.c
--- linux-2.6.17-rc6-git7-gregkh/drivers/usb/serial/usb-serial.c        
2006-06-16 21:28:46.000000000 -0700
+++ linux-2.6.17-rc6-git7-gregkh-v/drivers/usb/serial/usb-serial.c      
2006-06-17 21:35:49.000000000 -0700
@@ -41,6 +41,8 @@
 #define DRIVER_AUTHOR "Greg Kroah-Hartman, [EMAIL PROTECTED], 
http://www.kroah.com/linux/";
 #define DRIVER_DESC "USB Serial Driver core"
 
+static void port_free(struct usb_serial_port *port);
+
 /* Driver structure we register with the USB core */
 struct usb_driver usb_serial_driver = {
        .name =         "usbserial",
@@ -147,23 +149,10 @@ static void destroy_serial(struct kref *
                        port = serial->port[i];
                        if (!port)
                                continue;
-                       usb_kill_urb(port->read_urb);
-                       usb_free_urb(port->read_urb);
-                       usb_kill_urb(port->write_urb);
-                       usb_free_urb(port->write_urb);
-                       usb_kill_urb(port->interrupt_in_urb);
-                       usb_free_urb(port->interrupt_in_urb);
-                       usb_kill_urb(port->interrupt_out_urb);
-                       usb_free_urb(port->interrupt_out_urb);
-                       kfree(port->bulk_in_buffer);
-                       kfree(port->bulk_out_buffer);
-                       kfree(port->interrupt_in_buffer);
-                       kfree(port->interrupt_out_buffer);
+                       port_free(port);
                }
        }
 
-       flush_scheduled_work();         /* port->work */
-
        usb_put_dev(serial->dev);
 
        /* free up any memory that we allocated */
@@ -565,6 +554,11 @@ static void port_release(struct device *
        struct usb_serial_port *port = to_usb_serial_port(dev);
 
        dbg ("%s - %s", __FUNCTION__, dev->bus_id);
+       port_free(port);
+}
+
+static void port_free(struct usb_serial_port *port)
+{
        usb_kill_urb(port->read_urb);
        usb_free_urb(port->read_urb);
        usb_kill_urb(port->write_urb);
@@ -577,6 +571,7 @@ static void port_release(struct device *
        kfree(port->bulk_out_buffer);
        kfree(port->interrupt_in_buffer);
        kfree(port->interrupt_out_buffer);
+       flush_scheduled_work();         /* port->work */
        kfree(port);
 }
 
diff -urp -X dontdiff linux-2.6.17-rc6-git7-gregkh/drivers/usb/serial/visor.c 
linux-2.6.17-rc6-git7-gregkh-v/drivers/usb/serial/visor.c
--- linux-2.6.17-rc6-git7-gregkh/drivers/usb/serial/visor.c     2006-06-16 
21:28:45.000000000 -0700
+++ linux-2.6.17-rc6-git7-gregkh-v/drivers/usb/serial/visor.c   2006-06-17 
21:35:49.000000000 -0700
@@ -436,13 +436,25 @@ static int visor_write (struct usb_seria
 
 static int visor_write_room (struct usb_serial_port *port)
 {
+       struct visor_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
+
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        /*
         * We really can take anything the user throws at us
         * but let's pick a nice big number to tell the tty
-        * layer that we have lots of free space
+        * layer that we have lots of free space, unless we don't.
         */
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) {
+               spin_unlock_irqrestore(&priv->lock, flags);
+               dbg("%s - write limit hit\n", __FUNCTION__);
+               return 0;
+       }
+       spin_unlock_irqrestore(&priv->lock, flags);
+
        return 2048;
 }
 
@@ -764,8 +776,14 @@ static int generic_startup(struct usb_se
 
        for (i = 0; i < serial->num_ports; ++i) {
                priv = kzalloc (sizeof(*priv), GFP_KERNEL);
-               if (!priv)
+               if (!priv) {
+                       while (i-- != 0) {
+                               priv = 
usb_get_serial_port_data(serial->port[i]);
+                               usb_set_serial_port_data(serial->port[i], NULL);
+                               kfree(priv);
+                       }
                        return -ENOMEM;
+               }
                spin_lock_init(&priv->lock);
                usb_set_serial_port_data(serial->port[i], priv);
        }
@@ -877,7 +895,18 @@ static int clie_5_attach (struct usb_ser
 
 static void visor_shutdown (struct usb_serial *serial)
 {
+       struct visor_private *priv;
+       int i;
+
        dbg("%s", __FUNCTION__);
+
+       for (i = 0; i < serial->num_ports; i++) {
+               priv = usb_get_serial_port_data(serial->port[i]);
+               if (priv) {
+                       usb_set_serial_port_data(serial->port[i], NULL);
+                       kfree(priv);
+               }
+       }
 }
 
 static int visor_ioctl (struct usb_serial_port *port, struct file * file, 
unsigned int cmd, unsigned long arg)


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

Reply via email to