diff options
author | Pete Zaitcev <zaitcev@redhat.com> | 2006-06-21 18:03:40 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-07-12 19:03:21 -0400 |
commit | bd97c4f035b47c1a3ae5cc5ceccdda028b25e9d5 (patch) | |
tree | e866962fc6f316111ad5f8d767b40b9d3890885f /drivers/usb | |
parent | 34f8e761724ecbfe46246f3faa4c7dbfc3555c26 (diff) |
[PATCH] USB: fix visor leaks
This patch fixes blatant leaks in visor driver and makes it report
mode sensible things in ->write_room (this is only needed if your visor
is a terminal though).
It is made to fit into 80 columns with a temporary variable.
Might even save a few instructions...
Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/serial/visor.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 95a2936e902e..cbc21465f4fb 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -435,13 +435,25 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf, | |||
435 | 435 | ||
436 | static int visor_write_room (struct usb_serial_port *port) | 436 | static int visor_write_room (struct usb_serial_port *port) |
437 | { | 437 | { |
438 | struct visor_private *priv = usb_get_serial_port_data(port); | ||
439 | unsigned long flags; | ||
440 | |||
438 | dbg("%s - port %d", __FUNCTION__, port->number); | 441 | dbg("%s - port %d", __FUNCTION__, port->number); |
439 | 442 | ||
440 | /* | 443 | /* |
441 | * We really can take anything the user throws at us | 444 | * We really can take anything the user throws at us |
442 | * but let's pick a nice big number to tell the tty | 445 | * but let's pick a nice big number to tell the tty |
443 | * layer that we have lots of free space | 446 | * layer that we have lots of free space, unless we don't. |
444 | */ | 447 | */ |
448 | |||
449 | spin_lock_irqsave(&priv->lock, flags); | ||
450 | if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) { | ||
451 | spin_unlock_irqrestore(&priv->lock, flags); | ||
452 | dbg("%s - write limit hit\n", __FUNCTION__); | ||
453 | return 0; | ||
454 | } | ||
455 | spin_unlock_irqrestore(&priv->lock, flags); | ||
456 | |||
445 | return 2048; | 457 | return 2048; |
446 | } | 458 | } |
447 | 459 | ||
@@ -758,15 +770,22 @@ static int visor_calc_num_ports (struct usb_serial *serial) | |||
758 | 770 | ||
759 | static int generic_startup(struct usb_serial *serial) | 771 | static int generic_startup(struct usb_serial *serial) |
760 | { | 772 | { |
773 | struct usb_serial_port **ports = serial->port; | ||
761 | struct visor_private *priv; | 774 | struct visor_private *priv; |
762 | int i; | 775 | int i; |
763 | 776 | ||
764 | for (i = 0; i < serial->num_ports; ++i) { | 777 | for (i = 0; i < serial->num_ports; ++i) { |
765 | priv = kzalloc (sizeof(*priv), GFP_KERNEL); | 778 | priv = kzalloc (sizeof(*priv), GFP_KERNEL); |
766 | if (!priv) | 779 | if (!priv) { |
780 | while (i-- != 0) { | ||
781 | priv = usb_get_serial_port_data(ports[i]); | ||
782 | usb_set_serial_port_data(ports[i], NULL); | ||
783 | kfree(priv); | ||
784 | } | ||
767 | return -ENOMEM; | 785 | return -ENOMEM; |
786 | } | ||
768 | spin_lock_init(&priv->lock); | 787 | spin_lock_init(&priv->lock); |
769 | usb_set_serial_port_data(serial->port[i], priv); | 788 | usb_set_serial_port_data(ports[i], priv); |
770 | } | 789 | } |
771 | return 0; | 790 | return 0; |
772 | } | 791 | } |
@@ -876,7 +895,18 @@ static int clie_5_attach (struct usb_serial *serial) | |||
876 | 895 | ||
877 | static void visor_shutdown (struct usb_serial *serial) | 896 | static void visor_shutdown (struct usb_serial *serial) |
878 | { | 897 | { |
898 | struct visor_private *priv; | ||
899 | int i; | ||
900 | |||
879 | dbg("%s", __FUNCTION__); | 901 | dbg("%s", __FUNCTION__); |
902 | |||
903 | for (i = 0; i < serial->num_ports; i++) { | ||
904 | priv = usb_get_serial_port_data(serial->port[i]); | ||
905 | if (priv) { | ||
906 | usb_set_serial_port_data(serial->port[i], NULL); | ||
907 | kfree(priv); | ||
908 | } | ||
909 | } | ||
880 | } | 910 | } |
881 | 911 | ||
882 | static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) | 912 | static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) |