summaryrefslogtreecommitdiff
path: root/drivers/usb/serial/visor.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2007-04-30 12:38:01 +1000
committerPaul Mackerras <paulus@samba.org>2007-04-30 12:38:01 +1000
commit49e1900d4cc2e7bcecb681fe60f0990bec2dcce8 (patch)
tree253801ebf57e0a23856a2c7be129c2c178f62fdf /drivers/usb/serial/visor.c
parent34f6d749c0a328817d5e36274e53121c1db734dc (diff)
parentb9099ff63c75216d6ca10bce5a1abcd9293c27e6 (diff)
downloadlwn-49e1900d4cc2e7bcecb681fe60f0990bec2dcce8.tar.gz
lwn-49e1900d4cc2e7bcecb681fe60f0990bec2dcce8.zip
Merge branch 'linux-2.6' into for-2.6.22
Diffstat (limited to 'drivers/usb/serial/visor.c')
-rw-r--r--drivers/usb/serial/visor.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 2f59ff226e2c..ffbe601cde2a 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -384,19 +384,21 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
dbg("%s - write limit hit\n", __FUNCTION__);
return 0;
}
+ priv->outstanding_urbs++;
spin_unlock_irqrestore(&priv->lock, flags);
buffer = kmalloc (count, GFP_ATOMIC);
if (!buffer) {
dev_err(&port->dev, "out of memory\n");
- return -ENOMEM;
+ count = -ENOMEM;
+ goto error_no_buffer;
}
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
dev_err(&port->dev, "no more free urbs\n");
- kfree (buffer);
- return -ENOMEM;
+ count = -ENOMEM;
+ goto error_no_urb;
}
memcpy (buffer, buf, count);
@@ -415,19 +417,27 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n",
__FUNCTION__, status);
count = status;
- kfree (buffer);
+ goto error;
} else {
spin_lock_irqsave(&priv->lock, flags);
- ++priv->outstanding_urbs;
priv->bytes_out += count;
spin_unlock_irqrestore(&priv->lock, flags);
}
/* we are done with this urb, so let the host driver
* really free it when it is finished with it */
- usb_free_urb (urb);
+ usb_free_urb(urb);
return count;
+error:
+ usb_free_urb(urb);
+error_no_urb:
+ kfree(buffer);
+error_no_buffer:
+ spin_lock_irqsave(&priv->lock, flags);
+ --priv->outstanding_urbs;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return count;
}