Commit bd97c4f0 authored by Pete Zaitcev's avatar Pete Zaitcev Committed by Greg Kroah-Hartman
Browse files

[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: default avatarPete Zaitcev <zaitcev@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 34f8e761
Loading
Loading
Loading
Loading
+33 −3
Original line number Diff line number Diff line
@@ -435,13 +435,25 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,

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;
}

@@ -758,15 +770,22 @@ static int visor_calc_num_ports (struct usb_serial *serial)

static int generic_startup(struct usb_serial *serial)
{
	struct usb_serial_port **ports = serial->port;
	struct visor_private *priv;
	int i;

	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(ports[i]);
				usb_set_serial_port_data(ports[i], NULL);
				kfree(priv);
			}
			return -ENOMEM;
		}
		spin_lock_init(&priv->lock);
		usb_set_serial_port_data(serial->port[i], priv);
		usb_set_serial_port_data(ports[i], priv);
	}
	return 0;
}
@@ -876,7 +895,18 @@ static int clie_5_attach (struct usb_serial *serial)

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)