aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2009-12-24 06:42:09 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-02 17:53:37 -0500
commit66e47e6006a558b33c6f15bd2e072d52c40e0159 (patch)
tree200815045a299c9d85c5fbdc3b74554bc99ccdce /drivers
parent54f328d0c7221675e3c1647e1918172fec1b92c9 (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.c69
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,
1124static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) 1117static 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)
1782static void ftdi_dtr_rts(struct usb_serial_port *port, int on) 1761static 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;
2392out:
2393 kfree(buf);
2394 return ret;
2410} 2395}
2411 2396
2412static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, 2397static int ftdi_tiocmset(struct tty_struct *tty, struct file *file,