ChangeSet 1.1673.8.25, 2004/03/26 11:20:06-08:00, oliver@neukum.org [PATCH] USB: fix DMA to stack in ftdi driver this driver is doing DMA to the stack. Here's the obvious fix. drivers/usb/serial/ftdi_sio.c | 44 +++++++++++++++++++++++++++++++++--------- 1 files changed, 35 insertions(+), 9 deletions(-) diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c --- a/drivers/usb/serial/ftdi_sio.c Wed Apr 14 14:38:14 2004 +++ b/drivers/usb/serial/ftdi_sio.c Wed Apr 14 14:38:14 2004 @@ -790,8 +790,14 @@ static int set_rts(struct usb_serial_port *port, int high_or_low) { struct ftdi_private *priv = usb_get_serial_port_data(port); - char buf[1]; + char *buf; unsigned ftdi_high_or_low; + int rv; + + buf = kmalloc(1, GFP_NOIO); + if (!buf) + return -ENOMEM; + if (high_or_low) { ftdi_high_or_low = FTDI_SIO_SET_RTS_HIGH; priv->last_dtr_rts |= TIOCM_RTS; @@ -799,20 +805,29 @@ ftdi_high_or_low = FTDI_SIO_SET_RTS_LOW; priv->last_dtr_rts &= ~TIOCM_RTS; } - return(usb_control_msg(port->serial->dev, + rv = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), FTDI_SIO_SET_MODEM_CTRL_REQUEST, FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, ftdi_high_or_low, 0, - buf, 0, WDR_TIMEOUT)); + buf, 0, WDR_TIMEOUT); + + kfree(buf); + return rv; } static int set_dtr(struct usb_serial_port *port, int high_or_low) { struct ftdi_private *priv = usb_get_serial_port_data(port); - char buf[1]; + char *buf; unsigned ftdi_high_or_low; + int rv; + + buf = kmalloc(1, GFP_NOIO); + if (!buf) + return -ENOMEM; + if (high_or_low) { ftdi_high_or_low = FTDI_SIO_SET_DTR_HIGH; priv->last_dtr_rts |= TIOCM_DTR; @@ -820,12 +835,15 @@ ftdi_high_or_low = FTDI_SIO_SET_DTR_LOW; priv->last_dtr_rts &= ~TIOCM_DTR; } - return(usb_control_msg(port->serial->dev, + rv = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), FTDI_SIO_SET_MODEM_CTRL_REQUEST, FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, ftdi_high_or_low, 0, - buf, 0, WDR_TIMEOUT)); + buf, 0, WDR_TIMEOUT); + + kfree(buf); + return rv; } @@ -834,21 +852,29 @@ static int change_speed(struct usb_serial_port *port) { - char buf[1]; + char *buf; __u16 urb_value; __u16 urb_index; __u32 urb_index_value; + int rv; + + buf = kmalloc(1, GFP_NOIO); + if (!buf) + return -ENOMEM; urb_index_value = get_ftdi_divisor(port); urb_value = (__u16)urb_index_value; urb_index = (__u16)(urb_index_value >> 16); - return (usb_control_msg(port->serial->dev, + rv = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), FTDI_SIO_SET_BAUDRATE_REQUEST, FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, urb_value, urb_index, - buf, 0, 100) < 0); + buf, 0, 100); + + kfree(buf); + return rv; }