[ 056/101] USB: metro-usb: fix port-data memory leak
3.6-stable review patch. If anyone has any objections, please let me know. -- From: Johan Hovold commit 50dde8686eec41bf3d7cbec7a6f76c073ab01903 upstream. Fix port-data memory leak by moving port data allocation and deallocation to port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Note that the call to metrousb_clean (close) in shutdown was redundant. Compile-only tested. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/metro-usb.c | 50 ++--- 1 file changed, 13 insertions(+), 37 deletions(-) --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c @@ -280,51 +280,27 @@ static int metrousb_set_modem_ctrl(struc return retval; } -static void metrousb_shutdown(struct usb_serial *serial) +static int metrousb_port_probe(struct usb_serial_port *port) { - int i = 0; + struct metrousb_private *metro_priv; - dev_dbg(>dev->dev, "%s\n", __func__); + metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL); + if (!metro_priv) + return -ENOMEM; - /* Stop reading and writing on all ports. */ - for (i = 0; i < serial->num_ports; ++i) { - /* Close any open urbs. */ - metrousb_cleanup(serial->port[i]); + spin_lock_init(_priv->lock); - /* Free memory. */ - kfree(usb_get_serial_port_data(serial->port[i])); - usb_set_serial_port_data(serial->port[i], NULL); + usb_set_serial_port_data(port, metro_priv); - dev_dbg(>dev->dev, "%s - freed port number=%d\n", - __func__, serial->port[i]->number); - } + return 0; } -static int metrousb_startup(struct usb_serial *serial) +static int metrousb_port_remove(struct usb_serial_port *port) { struct metrousb_private *metro_priv; - struct usb_serial_port *port; - int i = 0; - - dev_dbg(>dev->dev, "%s\n", __func__); - /* Loop through the serial ports setting up the private structures. -* Currently we only use one port. */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - - /* Declare memory. */ - metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL); - if (!metro_priv) - return -ENOMEM; - - /* Initialize memory. */ - spin_lock_init(_priv->lock); - usb_set_serial_port_data(port, metro_priv); - - dev_dbg(>dev->dev, "%s - port number=%d\n ", - __func__, port->number); - } + metro_priv = usb_get_serial_port_data(port); + kfree(metro_priv); return 0; } @@ -423,8 +399,8 @@ static struct usb_serial_driver metrousb .close = metrousb_cleanup, .read_int_callback = metrousb_read_int_callback, .write_int_callback = metrousb_write_int_callback, - .attach = metrousb_startup, - .release= metrousb_shutdown, + .port_probe = metrousb_port_probe, + .port_remove= metrousb_port_remove, .throttle = metrousb_throttle, .unthrottle = metrousb_unthrottle, .tiocmget = metrousb_tiocmget, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[ 056/101] USB: metro-usb: fix port-data memory leak
3.6-stable review patch. If anyone has any objections, please let me know. -- From: Johan Hovold jhov...@gmail.com commit 50dde8686eec41bf3d7cbec7a6f76c073ab01903 upstream. Fix port-data memory leak by moving port data allocation and deallocation to port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Note that the call to metrousb_clean (close) in shutdown was redundant. Compile-only tested. Signed-off-by: Johan Hovold jhov...@gmail.com Signed-off-by: Greg Kroah-Hartman gre...@linuxfoundation.org --- drivers/usb/serial/metro-usb.c | 50 ++--- 1 file changed, 13 insertions(+), 37 deletions(-) --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c @@ -280,51 +280,27 @@ static int metrousb_set_modem_ctrl(struc return retval; } -static void metrousb_shutdown(struct usb_serial *serial) +static int metrousb_port_probe(struct usb_serial_port *port) { - int i = 0; + struct metrousb_private *metro_priv; - dev_dbg(serial-dev-dev, %s\n, __func__); + metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL); + if (!metro_priv) + return -ENOMEM; - /* Stop reading and writing on all ports. */ - for (i = 0; i serial-num_ports; ++i) { - /* Close any open urbs. */ - metrousb_cleanup(serial-port[i]); + spin_lock_init(metro_priv-lock); - /* Free memory. */ - kfree(usb_get_serial_port_data(serial-port[i])); - usb_set_serial_port_data(serial-port[i], NULL); + usb_set_serial_port_data(port, metro_priv); - dev_dbg(serial-dev-dev, %s - freed port number=%d\n, - __func__, serial-port[i]-number); - } + return 0; } -static int metrousb_startup(struct usb_serial *serial) +static int metrousb_port_remove(struct usb_serial_port *port) { struct metrousb_private *metro_priv; - struct usb_serial_port *port; - int i = 0; - - dev_dbg(serial-dev-dev, %s\n, __func__); - /* Loop through the serial ports setting up the private structures. -* Currently we only use one port. */ - for (i = 0; i serial-num_ports; ++i) { - port = serial-port[i]; - - /* Declare memory. */ - metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL); - if (!metro_priv) - return -ENOMEM; - - /* Initialize memory. */ - spin_lock_init(metro_priv-lock); - usb_set_serial_port_data(port, metro_priv); - - dev_dbg(serial-dev-dev, %s - port number=%d\n , - __func__, port-number); - } + metro_priv = usb_get_serial_port_data(port); + kfree(metro_priv); return 0; } @@ -423,8 +399,8 @@ static struct usb_serial_driver metrousb .close = metrousb_cleanup, .read_int_callback = metrousb_read_int_callback, .write_int_callback = metrousb_write_int_callback, - .attach = metrousb_startup, - .release= metrousb_shutdown, + .port_probe = metrousb_port_probe, + .port_remove= metrousb_port_remove, .throttle = metrousb_throttle, .unthrottle = metrousb_unthrottle, .tiocmget = metrousb_tiocmget, -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/