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