aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/visor.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/visor.c')
-rw-r--r--drivers/usb/serial/visor.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 9e89b8d54f72..88949f7884ca 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -13,7 +13,6 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/config.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/errno.h> 17#include <linux/errno.h>
19#include <linux/init.h> 18#include <linux/init.h>
@@ -26,7 +25,7 @@
26#include <linux/spinlock.h> 25#include <linux/spinlock.h>
27#include <asm/uaccess.h> 26#include <asm/uaccess.h>
28#include <linux/usb.h> 27#include <linux/usb.h>
29#include "usb-serial.h" 28#include <linux/usb/serial.h>
30#include "visor.h" 29#include "visor.h"
31 30
32/* 31/*
@@ -303,7 +302,6 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
303 spin_lock_irqsave(&priv->lock, flags); 302 spin_lock_irqsave(&priv->lock, flags);
304 priv->bytes_in = 0; 303 priv->bytes_in = 0;
305 priv->bytes_out = 0; 304 priv->bytes_out = 0;
306 priv->outstanding_urbs = 0;
307 priv->throttled = 0; 305 priv->throttled = 0;
308 spin_unlock_irqrestore(&priv->lock, flags); 306 spin_unlock_irqrestore(&priv->lock, flags);
309 307
@@ -436,13 +434,25 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
436 434
437static int visor_write_room (struct usb_serial_port *port) 435static int visor_write_room (struct usb_serial_port *port)
438{ 436{
437 struct visor_private *priv = usb_get_serial_port_data(port);
438 unsigned long flags;
439
439 dbg("%s - port %d", __FUNCTION__, port->number); 440 dbg("%s - port %d", __FUNCTION__, port->number);
440 441
441 /* 442 /*
442 * We really can take anything the user throws at us 443 * We really can take anything the user throws at us
443 * but let's pick a nice big number to tell the tty 444 * but let's pick a nice big number to tell the tty
444 * layer that we have lots of free space 445 * layer that we have lots of free space, unless we don't.
445 */ 446 */
447
448 spin_lock_irqsave(&priv->lock, flags);
449 if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) {
450 spin_unlock_irqrestore(&priv->lock, flags);
451 dbg("%s - write limit hit\n", __FUNCTION__);
452 return 0;
453 }
454 spin_unlock_irqrestore(&priv->lock, flags);
455
446 return 2048; 456 return 2048;
447} 457}
448 458
@@ -759,15 +769,22 @@ static int visor_calc_num_ports (struct usb_serial *serial)
759 769
760static int generic_startup(struct usb_serial *serial) 770static int generic_startup(struct usb_serial *serial)
761{ 771{
772 struct usb_serial_port **ports = serial->port;
762 struct visor_private *priv; 773 struct visor_private *priv;
763 int i; 774 int i;
764 775
765 for (i = 0; i < serial->num_ports; ++i) { 776 for (i = 0; i < serial->num_ports; ++i) {
766 priv = kzalloc (sizeof(*priv), GFP_KERNEL); 777 priv = kzalloc (sizeof(*priv), GFP_KERNEL);
767 if (!priv) 778 if (!priv) {
779 while (i-- != 0) {
780 priv = usb_get_serial_port_data(ports[i]);
781 usb_set_serial_port_data(ports[i], NULL);
782 kfree(priv);
783 }
768 return -ENOMEM; 784 return -ENOMEM;
785 }
769 spin_lock_init(&priv->lock); 786 spin_lock_init(&priv->lock);
770 usb_set_serial_port_data(serial->port[i], priv); 787 usb_set_serial_port_data(ports[i], priv);
771 } 788 }
772 return 0; 789 return 0;
773} 790}
@@ -877,7 +894,18 @@ static int clie_5_attach (struct usb_serial *serial)
877 894
878static void visor_shutdown (struct usb_serial *serial) 895static void visor_shutdown (struct usb_serial *serial)
879{ 896{
897 struct visor_private *priv;
898 int i;
899
880 dbg("%s", __FUNCTION__); 900 dbg("%s", __FUNCTION__);
901
902 for (i = 0; i < serial->num_ports; i++) {
903 priv = usb_get_serial_port_data(serial->port[i]);
904 if (priv) {
905 usb_set_serial_port_data(serial->port[i], NULL);
906 kfree(priv);
907 }
908 }
881} 909}
882 910
883static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) 911static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)