diff options
author | Johan Hovold <jhovold@gmail.com> | 2009-12-24 06:42:09 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-02 17:53:37 -0500 |
commit | 66e47e6006a558b33c6f15bd2e072d52c40e0159 (patch) | |
tree | 200815045a299c9d85c5fbdc3b74554bc99ccdce /drivers | |
parent | 54f328d0c7221675e3c1647e1918172fec1b92c9 (diff) |
USB: ftdi_sio: fix DMA buffers on stack
Also remove unnecessary buffer allocations for zero-length transfers.
Reported-by: Matti Aarnio <matti.aarnio@zmailer.org>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 69 |
1 files changed, 27 insertions, 42 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 59b6cbf020a0..a6e5a0d95566 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -935,7 +935,6 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
935 | unsigned int clear) | 935 | unsigned int clear) |
936 | { | 936 | { |
937 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 937 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
938 | char *buf; | ||
939 | unsigned urb_value; | 938 | unsigned urb_value; |
940 | int rv; | 939 | int rv; |
941 | 940 | ||
@@ -944,10 +943,6 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
944 | return 0; /* no change */ | 943 | return 0; /* no change */ |
945 | } | 944 | } |
946 | 945 | ||
947 | buf = kmalloc(1, GFP_NOIO); | ||
948 | if (!buf) | ||
949 | return -ENOMEM; | ||
950 | |||
951 | clear &= ~set; /* 'set' takes precedence over 'clear' */ | 946 | clear &= ~set; /* 'set' takes precedence over 'clear' */ |
952 | urb_value = 0; | 947 | urb_value = 0; |
953 | if (clear & TIOCM_DTR) | 948 | if (clear & TIOCM_DTR) |
@@ -963,9 +958,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
963 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, | 958 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, |
964 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, | 959 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, |
965 | urb_value, priv->interface, | 960 | urb_value, priv->interface, |
966 | buf, 0, WDR_TIMEOUT); | 961 | NULL, 0, WDR_TIMEOUT); |
967 | |||
968 | kfree(buf); | ||
969 | if (rv < 0) { | 962 | if (rv < 0) { |
970 | dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", | 963 | dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", |
971 | __func__, | 964 | __func__, |
@@ -1124,16 +1117,11 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, | |||
1124 | static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) | 1117 | static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) |
1125 | { | 1118 | { |
1126 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1119 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1127 | char *buf; | ||
1128 | __u16 urb_value; | 1120 | __u16 urb_value; |
1129 | __u16 urb_index; | 1121 | __u16 urb_index; |
1130 | __u32 urb_index_value; | 1122 | __u32 urb_index_value; |
1131 | int rv; | 1123 | int rv; |
1132 | 1124 | ||
1133 | buf = kmalloc(1, GFP_NOIO); | ||
1134 | if (!buf) | ||
1135 | return -ENOMEM; | ||
1136 | |||
1137 | urb_index_value = get_ftdi_divisor(tty, port); | 1125 | urb_index_value = get_ftdi_divisor(tty, port); |
1138 | urb_value = (__u16)urb_index_value; | 1126 | urb_value = (__u16)urb_index_value; |
1139 | urb_index = (__u16)(urb_index_value >> 16); | 1127 | urb_index = (__u16)(urb_index_value >> 16); |
@@ -1146,9 +1134,7 @@ static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) | |||
1146 | FTDI_SIO_SET_BAUDRATE_REQUEST, | 1134 | FTDI_SIO_SET_BAUDRATE_REQUEST, |
1147 | FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, | 1135 | FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, |
1148 | urb_value, urb_index, | 1136 | urb_value, urb_index, |
1149 | buf, 0, WDR_SHORT_TIMEOUT); | 1137 | NULL, 0, WDR_SHORT_TIMEOUT); |
1150 | |||
1151 | kfree(buf); | ||
1152 | return rv; | 1138 | return rv; |
1153 | } | 1139 | } |
1154 | 1140 | ||
@@ -1156,7 +1142,6 @@ static int write_latency_timer(struct usb_serial_port *port) | |||
1156 | { | 1142 | { |
1157 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1143 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1158 | struct usb_device *udev = port->serial->dev; | 1144 | struct usb_device *udev = port->serial->dev; |
1159 | char buf[1]; | ||
1160 | int rv = 0; | 1145 | int rv = 0; |
1161 | int l = priv->latency; | 1146 | int l = priv->latency; |
1162 | 1147 | ||
@@ -1170,8 +1155,7 @@ static int write_latency_timer(struct usb_serial_port *port) | |||
1170 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | 1155 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, |
1171 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | 1156 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, |
1172 | l, priv->interface, | 1157 | l, priv->interface, |
1173 | buf, 0, WDR_TIMEOUT); | 1158 | NULL, 0, WDR_TIMEOUT); |
1174 | |||
1175 | if (rv < 0) | 1159 | if (rv < 0) |
1176 | dev_err(&port->dev, "Unable to write latency timer: %i\n", rv); | 1160 | dev_err(&port->dev, "Unable to write latency timer: %i\n", rv); |
1177 | return rv; | 1161 | return rv; |
@@ -1445,7 +1429,6 @@ static ssize_t store_event_char(struct device *dev, | |||
1445 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1429 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1446 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1430 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1447 | struct usb_device *udev = port->serial->dev; | 1431 | struct usb_device *udev = port->serial->dev; |
1448 | char buf[1]; | ||
1449 | int v = simple_strtoul(valbuf, NULL, 10); | 1432 | int v = simple_strtoul(valbuf, NULL, 10); |
1450 | int rv = 0; | 1433 | int rv = 0; |
1451 | 1434 | ||
@@ -1456,8 +1439,7 @@ static ssize_t store_event_char(struct device *dev, | |||
1456 | FTDI_SIO_SET_EVENT_CHAR_REQUEST, | 1439 | FTDI_SIO_SET_EVENT_CHAR_REQUEST, |
1457 | FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, | 1440 | FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, |
1458 | v, priv->interface, | 1441 | v, priv->interface, |
1459 | buf, 0, WDR_TIMEOUT); | 1442 | NULL, 0, WDR_TIMEOUT); |
1460 | |||
1461 | if (rv < 0) { | 1443 | if (rv < 0) { |
1462 | dbg("Unable to write event character: %i", rv); | 1444 | dbg("Unable to write event character: %i", rv); |
1463 | return -EIO; | 1445 | return -EIO; |
@@ -1636,7 +1618,6 @@ static int ftdi_NDI_device_setup(struct usb_serial *serial) | |||
1636 | struct usb_device *udev = serial->dev; | 1618 | struct usb_device *udev = serial->dev; |
1637 | int latency = ndi_latency_timer; | 1619 | int latency = ndi_latency_timer; |
1638 | int rv = 0; | 1620 | int rv = 0; |
1639 | char buf[1]; | ||
1640 | 1621 | ||
1641 | if (latency == 0) | 1622 | if (latency == 0) |
1642 | latency = 1; | 1623 | latency = 1; |
@@ -1649,7 +1630,7 @@ static int ftdi_NDI_device_setup(struct usb_serial *serial) | |||
1649 | rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 1630 | rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
1650 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | 1631 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, |
1651 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | 1632 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, |
1652 | latency, 0, buf, 0, WDR_TIMEOUT); | 1633 | latency, 0, NULL, 0, WDR_TIMEOUT); |
1653 | return 0; | 1634 | return 0; |
1654 | } | 1635 | } |
1655 | 1636 | ||
@@ -1737,9 +1718,7 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1737 | struct usb_device *dev = port->serial->dev; | 1718 | struct usb_device *dev = port->serial->dev; |
1738 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1719 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1739 | unsigned long flags; | 1720 | unsigned long flags; |
1740 | |||
1741 | int result = 0; | 1721 | int result = 0; |
1742 | char buf[1]; /* Needed for the usb_control_msg I think */ | ||
1743 | 1722 | ||
1744 | dbg("%s", __func__); | 1723 | dbg("%s", __func__); |
1745 | 1724 | ||
@@ -1754,7 +1733,7 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1754 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1733 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1755 | FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, | 1734 | FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, |
1756 | FTDI_SIO_RESET_SIO, | 1735 | FTDI_SIO_RESET_SIO, |
1757 | priv->interface, buf, 0, WDR_TIMEOUT); | 1736 | priv->interface, NULL, 0, WDR_TIMEOUT); |
1758 | 1737 | ||
1759 | /* Termios defaults are set by usb_serial_init. We don't change | 1738 | /* Termios defaults are set by usb_serial_init. We don't change |
1760 | port->tty->termios - this would lose speed settings, etc. | 1739 | port->tty->termios - this would lose speed settings, etc. |
@@ -1782,7 +1761,6 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1782 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | 1761 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on) |
1783 | { | 1762 | { |
1784 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1763 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1785 | char buf[1]; | ||
1786 | 1764 | ||
1787 | mutex_lock(&port->serial->disc_mutex); | 1765 | mutex_lock(&port->serial->disc_mutex); |
1788 | if (!port->serial->disconnected) { | 1766 | if (!port->serial->disconnected) { |
@@ -1791,7 +1769,7 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | |||
1791 | usb_sndctrlpipe(port->serial->dev, 0), | 1769 | usb_sndctrlpipe(port->serial->dev, 0), |
1792 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 1770 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
1793 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 1771 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
1794 | 0, priv->interface, buf, 0, | 1772 | 0, priv->interface, NULL, 0, |
1795 | WDR_TIMEOUT) < 0) { | 1773 | WDR_TIMEOUT) < 0) { |
1796 | dev_err(&port->dev, "error from flowcontrol urb\n"); | 1774 | dev_err(&port->dev, "error from flowcontrol urb\n"); |
1797 | } | 1775 | } |
@@ -2160,7 +2138,6 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | |||
2160 | struct usb_serial_port *port = tty->driver_data; | 2138 | struct usb_serial_port *port = tty->driver_data; |
2161 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2139 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2162 | __u16 urb_value = 0; | 2140 | __u16 urb_value = 0; |
2163 | char buf[1]; | ||
2164 | 2141 | ||
2165 | /* break_state = -1 to turn on break, and 0 to turn off break */ | 2142 | /* break_state = -1 to turn on break, and 0 to turn off break */ |
2166 | /* see drivers/char/tty_io.c to see it used */ | 2143 | /* see drivers/char/tty_io.c to see it used */ |
@@ -2176,7 +2153,7 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | |||
2176 | FTDI_SIO_SET_DATA_REQUEST, | 2153 | FTDI_SIO_SET_DATA_REQUEST, |
2177 | FTDI_SIO_SET_DATA_REQUEST_TYPE, | 2154 | FTDI_SIO_SET_DATA_REQUEST_TYPE, |
2178 | urb_value , priv->interface, | 2155 | urb_value , priv->interface, |
2179 | buf, 0, WDR_TIMEOUT) < 0) { | 2156 | NULL, 0, WDR_TIMEOUT) < 0) { |
2180 | dev_err(&port->dev, "%s FAILED to enable/disable break state " | 2157 | dev_err(&port->dev, "%s FAILED to enable/disable break state " |
2181 | "(state was %d)\n", __func__, break_state); | 2158 | "(state was %d)\n", __func__, break_state); |
2182 | } | 2159 | } |
@@ -2200,7 +2177,6 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2200 | struct ktermios *termios = tty->termios; | 2177 | struct ktermios *termios = tty->termios; |
2201 | unsigned int cflag = termios->c_cflag; | 2178 | unsigned int cflag = termios->c_cflag; |
2202 | __u16 urb_value; /* will hold the new flags */ | 2179 | __u16 urb_value; /* will hold the new flags */ |
2203 | char buf[1]; /* Perhaps I should dynamically alloc this? */ | ||
2204 | 2180 | ||
2205 | /* Added for xon/xoff support */ | 2181 | /* Added for xon/xoff support */ |
2206 | unsigned int iflag = termios->c_iflag; | 2182 | unsigned int iflag = termios->c_iflag; |
@@ -2266,7 +2242,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2266 | FTDI_SIO_SET_DATA_REQUEST, | 2242 | FTDI_SIO_SET_DATA_REQUEST, |
2267 | FTDI_SIO_SET_DATA_REQUEST_TYPE, | 2243 | FTDI_SIO_SET_DATA_REQUEST_TYPE, |
2268 | urb_value , priv->interface, | 2244 | urb_value , priv->interface, |
2269 | buf, 0, WDR_SHORT_TIMEOUT) < 0) { | 2245 | NULL, 0, WDR_SHORT_TIMEOUT) < 0) { |
2270 | dev_err(&port->dev, "%s FAILED to set " | 2246 | dev_err(&port->dev, "%s FAILED to set " |
2271 | "databits/stopbits/parity\n", __func__); | 2247 | "databits/stopbits/parity\n", __func__); |
2272 | } | 2248 | } |
@@ -2278,7 +2254,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2278 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2254 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2279 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2255 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2280 | 0, priv->interface, | 2256 | 0, priv->interface, |
2281 | buf, 0, WDR_TIMEOUT) < 0) { | 2257 | NULL, 0, WDR_TIMEOUT) < 0) { |
2282 | dev_err(&port->dev, | 2258 | dev_err(&port->dev, |
2283 | "%s error from disable flowcontrol urb\n", | 2259 | "%s error from disable flowcontrol urb\n", |
2284 | __func__); | 2260 | __func__); |
@@ -2304,7 +2280,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2304 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2280 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2305 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2281 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2306 | 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), | 2282 | 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), |
2307 | buf, 0, WDR_TIMEOUT) < 0) { | 2283 | NULL, 0, WDR_TIMEOUT) < 0) { |
2308 | dev_err(&port->dev, | 2284 | dev_err(&port->dev, |
2309 | "urb failed to set to rts/cts flow control\n"); | 2285 | "urb failed to set to rts/cts flow control\n"); |
2310 | } | 2286 | } |
@@ -2336,7 +2312,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2336 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2312 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2337 | urb_value , (FTDI_SIO_XON_XOFF_HS | 2313 | urb_value , (FTDI_SIO_XON_XOFF_HS |
2338 | | priv->interface), | 2314 | | priv->interface), |
2339 | buf, 0, WDR_TIMEOUT) < 0) { | 2315 | NULL, 0, WDR_TIMEOUT) < 0) { |
2340 | dev_err(&port->dev, "urb failed to set to " | 2316 | dev_err(&port->dev, "urb failed to set to " |
2341 | "xon/xoff flow control\n"); | 2317 | "xon/xoff flow control\n"); |
2342 | } | 2318 | } |
@@ -2350,7 +2326,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2350 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2326 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2351 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2327 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2352 | 0, priv->interface, | 2328 | 0, priv->interface, |
2353 | buf, 0, WDR_TIMEOUT) < 0) { | 2329 | NULL, 0, WDR_TIMEOUT) < 0) { |
2354 | dev_err(&port->dev, | 2330 | dev_err(&port->dev, |
2355 | "urb failed to clear flow control\n"); | 2331 | "urb failed to clear flow control\n"); |
2356 | } | 2332 | } |
@@ -2364,10 +2340,15 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2364 | { | 2340 | { |
2365 | struct usb_serial_port *port = tty->driver_data; | 2341 | struct usb_serial_port *port = tty->driver_data; |
2366 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2342 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2367 | unsigned char buf[2]; | 2343 | unsigned char *buf; |
2368 | int ret; | 2344 | int ret; |
2369 | 2345 | ||
2370 | dbg("%s TIOCMGET", __func__); | 2346 | dbg("%s TIOCMGET", __func__); |
2347 | |||
2348 | buf = kmalloc(2, GFP_KERNEL); | ||
2349 | if (!buf) | ||
2350 | return -ENOMEM; | ||
2351 | |||
2371 | switch (priv->chip_type) { | 2352 | switch (priv->chip_type) { |
2372 | case SIO: | 2353 | case SIO: |
2373 | /* Request the status from the device */ | 2354 | /* Request the status from the device */ |
@@ -2378,7 +2359,7 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2378 | 0, 0, | 2359 | 0, 0, |
2379 | buf, 1, WDR_TIMEOUT); | 2360 | buf, 1, WDR_TIMEOUT); |
2380 | if (ret < 0) | 2361 | if (ret < 0) |
2381 | return ret; | 2362 | goto out; |
2382 | break; | 2363 | break; |
2383 | case FT8U232AM: | 2364 | case FT8U232AM: |
2384 | case FT232BM: | 2365 | case FT232BM: |
@@ -2396,17 +2377,21 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2396 | 0, priv->interface, | 2377 | 0, priv->interface, |
2397 | buf, 2, WDR_TIMEOUT); | 2378 | buf, 2, WDR_TIMEOUT); |
2398 | if (ret < 0) | 2379 | if (ret < 0) |
2399 | return ret; | 2380 | goto out; |
2400 | break; | 2381 | break; |
2401 | default: | 2382 | default: |
2402 | return -EFAULT; | 2383 | ret = -EFAULT; |
2384 | goto out; | ||
2403 | } | 2385 | } |
2404 | 2386 | ||
2405 | return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | | 2387 | ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | |
2406 | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | | 2388 | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | |
2407 | (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | | 2389 | (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | |
2408 | (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | | 2390 | (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | |
2409 | priv->last_dtr_rts; | 2391 | priv->last_dtr_rts; |
2392 | out: | ||
2393 | kfree(buf); | ||
2394 | return ret; | ||
2410 | } | 2395 | } |
2411 | 2396 | ||
2412 | static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, | 2397 | static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, |