Message ID | 20180518132550.21749-5-johan@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, May 18, 2018 at 03:25:50PM +0200, Johan Hovold wrote: > Clean up the somewhat convoluted hardware-assisted flow control > handling. > > Signed-off-by: Johan Hovold <johan@kernel.org> > --- > drivers/usb/serial/ftdi_sio.c | 81 ++++++++++------------------------- > 1 file changed, 23 insertions(+), 58 deletions(-) > > diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c > index 3d7f181e7e2a..b5cef322826f 100644 > --- a/drivers/usb/serial/ftdi_sio.c > +++ b/drivers/usb/serial/ftdi_sio.c > @@ -2191,12 +2191,8 @@ static void ftdi_set_termios(struct tty_struct *tty, > struct ftdi_private *priv = usb_get_serial_port_data(port); > struct ktermios *termios = &tty->termios; > unsigned int cflag = termios->c_cflag; > - u16 value; > - > - /* Added for xon/xoff support */ > - unsigned int iflag = termios->c_iflag; > - unsigned char vstop; > - unsigned char vstart; > + u16 value, index; > + int ret; > > /* Force baud rate if this device requires it, unless it is set to > B0. */ > @@ -2325,61 +2321,30 @@ static void ftdi_set_termios(struct tty_struct *tty, > set_mctrl(port, TIOCM_DTR | TIOCM_RTS); > } > > - /* Set flow control */ > - /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ > no_c_cflag_changes: > - if (cflag & CRTSCTS) { > - dev_dbg(ddev, "%s Setting to CRTSCTS flow control\n", __func__); > - if (usb_control_msg(dev, > - usb_sndctrlpipe(dev, 0), > - FTDI_SIO_SET_FLOW_CTRL_REQUEST, > - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, > - 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), > - NULL, 0, WDR_TIMEOUT) < 0) { > - dev_err(ddev, "urb failed to set to rts/cts flow control\n"); > - } > + /* Set hardware-assisted flow control */ > + value = 0; > + > + if (C_CRTSCTS(tty)) { > + dev_dbg(&port->dev, "enabling rts/cts flow control\n"); > + index = FTDI_SIO_RTS_CTS_HS; > + } else if (I_IXON(tty)) { > + dev_dbg(&port->dev, "enabling xon/xoff flow control\n"); > + index = FTDI_SIO_XON_XOFF_HS; > + value = STOP_CHAR(tty) << 8 | START_CHAR(tty); > } else { > - /* > - * Xon/Xoff code > - */ > - if (iflag & IXON) { > - dev_dbg(ddev, "%s request to enable xonxoff iflag=%04x\n", > - __func__, iflag); > - /* Try to enable the XON/XOFF on the ftdi_sio > - * Set the vstart and vstop -- could have been done up > - * above where a lot of other dereferencing is done but > - * that would be very inefficient as vstart and vstop > - * are not always needed. > - */ > - vstart = termios->c_cc[VSTART]; > - vstop = termios->c_cc[VSTOP]; > - value = (vstop << 8) | (vstart); > - > - if (usb_control_msg(dev, > - usb_sndctrlpipe(dev, 0), > - FTDI_SIO_SET_FLOW_CTRL_REQUEST, > - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, > - value , (FTDI_SIO_XON_XOFF_HS > - | priv->interface), > - NULL, 0, WDR_TIMEOUT) < 0) { > - dev_err(&port->dev, "urb failed to set to " > - "xon/xoff flow control\n"); > - } > - } else { > - /* else clause to only run if cflag ! CRTSCTS and iflag > - * ! XON. CHECKME Assuming XON/XOFF handled by tty > - * stack - not by device */ > - dev_dbg(ddev, "%s Turning off hardware flow control\n", __func__); > - if (usb_control_msg(dev, > - usb_sndctrlpipe(dev, 0), > - FTDI_SIO_SET_FLOW_CTRL_REQUEST, > - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, > - 0, priv->interface, > - NULL, 0, WDR_TIMEOUT) < 0) { > - dev_err(ddev, "urb failed to clear flow control\n"); > - } > - } > + dev_dbg(&port->dev, "disabling flow control\n"); > + index = FTDI_SIO_DISABLE_FLOW_CTRL; > } > + > + index |= priv->interface; > + > + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), > + FTDI_SIO_SET_FLOW_CTRL_REQUEST, > + FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, > + value, index, NULL, 0, WDR_TIMEOUT); > + if (ret < 0) > + dev_err(&port->dev, "failed to set flow control: %d\n", ret); > } > > /* Wow, much simpler, nice work. Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 3d7f181e7e2a..b5cef322826f 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2191,12 +2191,8 @@ static void ftdi_set_termios(struct tty_struct *tty, struct ftdi_private *priv = usb_get_serial_port_data(port); struct ktermios *termios = &tty->termios; unsigned int cflag = termios->c_cflag; - u16 value; - - /* Added for xon/xoff support */ - unsigned int iflag = termios->c_iflag; - unsigned char vstop; - unsigned char vstart; + u16 value, index; + int ret; /* Force baud rate if this device requires it, unless it is set to B0. */ @@ -2325,61 +2321,30 @@ static void ftdi_set_termios(struct tty_struct *tty, set_mctrl(port, TIOCM_DTR | TIOCM_RTS); } - /* Set flow control */ - /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ no_c_cflag_changes: - if (cflag & CRTSCTS) { - dev_dbg(ddev, "%s Setting to CRTSCTS flow control\n", __func__); - if (usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - FTDI_SIO_SET_FLOW_CTRL_REQUEST, - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), - NULL, 0, WDR_TIMEOUT) < 0) { - dev_err(ddev, "urb failed to set to rts/cts flow control\n"); - } + /* Set hardware-assisted flow control */ + value = 0; + + if (C_CRTSCTS(tty)) { + dev_dbg(&port->dev, "enabling rts/cts flow control\n"); + index = FTDI_SIO_RTS_CTS_HS; + } else if (I_IXON(tty)) { + dev_dbg(&port->dev, "enabling xon/xoff flow control\n"); + index = FTDI_SIO_XON_XOFF_HS; + value = STOP_CHAR(tty) << 8 | START_CHAR(tty); } else { - /* - * Xon/Xoff code - */ - if (iflag & IXON) { - dev_dbg(ddev, "%s request to enable xonxoff iflag=%04x\n", - __func__, iflag); - /* Try to enable the XON/XOFF on the ftdi_sio - * Set the vstart and vstop -- could have been done up - * above where a lot of other dereferencing is done but - * that would be very inefficient as vstart and vstop - * are not always needed. - */ - vstart = termios->c_cc[VSTART]; - vstop = termios->c_cc[VSTOP]; - value = (vstop << 8) | (vstart); - - if (usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - FTDI_SIO_SET_FLOW_CTRL_REQUEST, - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - value , (FTDI_SIO_XON_XOFF_HS - | priv->interface), - NULL, 0, WDR_TIMEOUT) < 0) { - dev_err(&port->dev, "urb failed to set to " - "xon/xoff flow control\n"); - } - } else { - /* else clause to only run if cflag ! CRTSCTS and iflag - * ! XON. CHECKME Assuming XON/XOFF handled by tty - * stack - not by device */ - dev_dbg(ddev, "%s Turning off hardware flow control\n", __func__); - if (usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - FTDI_SIO_SET_FLOW_CTRL_REQUEST, - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, - 0, priv->interface, - NULL, 0, WDR_TIMEOUT) < 0) { - dev_err(ddev, "urb failed to clear flow control\n"); - } - } + dev_dbg(&port->dev, "disabling flow control\n"); + index = FTDI_SIO_DISABLE_FLOW_CTRL; } + + index |= priv->interface; + + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + FTDI_SIO_SET_FLOW_CTRL_REQUEST, + FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, + value, index, NULL, 0, WDR_TIMEOUT); + if (ret < 0) + dev_err(&port->dev, "failed to set flow control: %d\n", ret); } /*
Clean up the somewhat convoluted hardware-assisted flow control handling. Signed-off-by: Johan Hovold <johan@kernel.org> --- drivers/usb/serial/ftdi_sio.c | 81 ++++++++++------------------------- 1 file changed, 23 insertions(+), 58 deletions(-)