summaryrefslogtreecommitdiff
path: root/drivers/usb/serial/ftdi_sio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-27 14:19:17 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-27 14:19:17 -0700
commit50f732ee63b91eb08a29974b36bd63e1150bb642 (patch)
treefdfc63411a34ffbe26a3b0a997aaeff742a0301b /drivers/usb/serial/ftdi_sio.c
parentaa5bc2b58e3344da57f26b62e99e13e91c9e0a94 (diff)
parenta7205b30106a2d4ee268132644cdb292da2d9b41 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (78 commits) USB: update MAINAINERS and CREDITS for Freescale USB driver USB: update gadget files for fsl_usb2_udc driver USB: add Freescale high-speed USB SOC device controller driver USB: quirk for broken suspend of IT8152F/G USB: iowarrior.c: timeouts too small in usb_control_msg calls USB: dell device id for option.c USB: Remove Huawei unusual_devs entry USB: CP2101 New Device IDs USB: add picdem device to ldusb usbfs micro optimitation USB: remove ancient/broken CRIS hcd usb ethernet gadget, workaround network stack API glitch USB: add "busnum" attribute for USB devices USB: cxacru: ADSL state management usbatm: Detect usb device shutdown and ignore failed urbs USB: Remove duplicate define of OHCI_QUIRK_ZFMICRO USB: BandRich BandLuxe HSDPA Data Card Driver USB gadget rndis: fix struct rndis_packet_msg_type unaligned bug USB Elan FTDI: check for driver registration status USB: sierra: add more checks on shutdown ...
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r--drivers/usb/serial/ftdi_sio.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 8ff9d54b21e6..95a1805b064f 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -342,6 +342,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_USBX_707_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) },
{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) },
@@ -1433,6 +1434,7 @@ static int ftdi_write (struct usb_serial_port *port,
dbg("%s - write limit hit\n", __FUNCTION__);
return 0;
}
+ priv->tx_outstanding_urbs++;
spin_unlock_irqrestore(&priv->tx_lock, flags);
data_offset = priv->write_offset;
@@ -1450,14 +1452,15 @@ static int ftdi_write (struct usb_serial_port *port,
buffer = kmalloc (transfer_size, GFP_ATOMIC);
if (!buffer) {
err("%s ran out of kernel memory for urb ...", __FUNCTION__);
- return -ENOMEM;
+ count = -ENOMEM;
+ goto error_no_buffer;
}
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
err("%s - no more free urbs", __FUNCTION__);
- kfree (buffer);
- return -ENOMEM;
+ count = -ENOMEM;
+ goto error_no_urb;
}
/* Copy data */
@@ -1499,10 +1502,9 @@ static int ftdi_write (struct usb_serial_port *port,
if (status) {
err("%s - failed submitting write urb, error %d", __FUNCTION__, status);
count = status;
- kfree (buffer);
+ goto error;
} else {
spin_lock_irqsave(&priv->tx_lock, flags);
- ++priv->tx_outstanding_urbs;
priv->tx_outstanding_bytes += count;
priv->tx_bytes += count;
spin_unlock_irqrestore(&priv->tx_lock, flags);
@@ -1510,10 +1512,19 @@ static int ftdi_write (struct usb_serial_port *port,
/* 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);
dbg("%s write returning: %d", __FUNCTION__, count);
return count;
+error:
+ usb_free_urb(urb);
+error_no_urb:
+ kfree (buffer);
+error_no_buffer:
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ priv->tx_outstanding_urbs--;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ return count;
} /* ftdi_write */