Loading drivers/usb/serial/ftdi_sio.c +23 −58 Original line number Original line Diff line number Diff line Loading @@ -2191,12 +2191,8 @@ static void ftdi_set_termios(struct tty_struct *tty, struct ftdi_private *priv = usb_get_serial_port_data(port); struct ftdi_private *priv = usb_get_serial_port_data(port); struct ktermios *termios = &tty->termios; struct ktermios *termios = &tty->termios; unsigned int cflag = termios->c_cflag; unsigned int cflag = termios->c_cflag; u16 value; u16 value, index; int ret; /* Added for xon/xoff support */ unsigned int iflag = termios->c_iflag; unsigned char vstop; unsigned char vstart; /* Force baud rate if this device requires it, unless it is set to /* Force baud rate if this device requires it, unless it is set to B0. */ B0. */ Loading Loading @@ -2325,61 +2321,30 @@ static void ftdi_set_termios(struct tty_struct *tty, set_mctrl(port, TIOCM_DTR | TIOCM_RTS); 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: no_c_cflag_changes: if (cflag & CRTSCTS) { /* Set hardware-assisted flow control */ dev_dbg(ddev, "%s Setting to CRTSCTS flow control\n", __func__); value = 0; 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"); } } 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, if (C_CRTSCTS(tty)) { usb_sndctrlpipe(dev, 0), dev_dbg(&port->dev, "enabling rts/cts flow control\n"); FTDI_SIO_SET_FLOW_CTRL_REQUEST, index = FTDI_SIO_RTS_CTS_HS; FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, } else if (I_IXON(tty)) { value , (FTDI_SIO_XON_XOFF_HS dev_dbg(&port->dev, "enabling xon/xoff flow control\n"); | priv->interface), index = FTDI_SIO_XON_XOFF_HS; NULL, 0, WDR_TIMEOUT) < 0) { value = STOP_CHAR(tty) << 8 | START_CHAR(tty); dev_err(&port->dev, "urb failed to set to " "xon/xoff flow control\n"); } } else { } else { /* else clause to only run if cflag ! CRTSCTS and iflag dev_dbg(&port->dev, "disabling flow control\n"); * ! XON. CHECKME Assuming XON/XOFF handled by tty index = FTDI_SIO_DISABLE_FLOW_CTRL; * stack - not by device */ } dev_dbg(ddev, "%s Turning off hardware flow control\n", __func__); if (usb_control_msg(dev, index |= priv->interface; usb_sndctrlpipe(dev, 0), ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 0, priv->interface, value, index, NULL, 0, WDR_TIMEOUT); NULL, 0, WDR_TIMEOUT) < 0) { if (ret < 0) dev_err(ddev, "urb failed to clear flow control\n"); dev_err(&port->dev, "failed to set flow control: %d\n", ret); } } } } } /* /* Loading Loading
drivers/usb/serial/ftdi_sio.c +23 −58 Original line number Original line Diff line number Diff line Loading @@ -2191,12 +2191,8 @@ static void ftdi_set_termios(struct tty_struct *tty, struct ftdi_private *priv = usb_get_serial_port_data(port); struct ftdi_private *priv = usb_get_serial_port_data(port); struct ktermios *termios = &tty->termios; struct ktermios *termios = &tty->termios; unsigned int cflag = termios->c_cflag; unsigned int cflag = termios->c_cflag; u16 value; u16 value, index; int ret; /* Added for xon/xoff support */ unsigned int iflag = termios->c_iflag; unsigned char vstop; unsigned char vstart; /* Force baud rate if this device requires it, unless it is set to /* Force baud rate if this device requires it, unless it is set to B0. */ B0. */ Loading Loading @@ -2325,61 +2321,30 @@ static void ftdi_set_termios(struct tty_struct *tty, set_mctrl(port, TIOCM_DTR | TIOCM_RTS); 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: no_c_cflag_changes: if (cflag & CRTSCTS) { /* Set hardware-assisted flow control */ dev_dbg(ddev, "%s Setting to CRTSCTS flow control\n", __func__); value = 0; 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"); } } 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, if (C_CRTSCTS(tty)) { usb_sndctrlpipe(dev, 0), dev_dbg(&port->dev, "enabling rts/cts flow control\n"); FTDI_SIO_SET_FLOW_CTRL_REQUEST, index = FTDI_SIO_RTS_CTS_HS; FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, } else if (I_IXON(tty)) { value , (FTDI_SIO_XON_XOFF_HS dev_dbg(&port->dev, "enabling xon/xoff flow control\n"); | priv->interface), index = FTDI_SIO_XON_XOFF_HS; NULL, 0, WDR_TIMEOUT) < 0) { value = STOP_CHAR(tty) << 8 | START_CHAR(tty); dev_err(&port->dev, "urb failed to set to " "xon/xoff flow control\n"); } } else { } else { /* else clause to only run if cflag ! CRTSCTS and iflag dev_dbg(&port->dev, "disabling flow control\n"); * ! XON. CHECKME Assuming XON/XOFF handled by tty index = FTDI_SIO_DISABLE_FLOW_CTRL; * stack - not by device */ } dev_dbg(ddev, "%s Turning off hardware flow control\n", __func__); if (usb_control_msg(dev, index |= priv->interface; usb_sndctrlpipe(dev, 0), ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 0, priv->interface, value, index, NULL, 0, WDR_TIMEOUT); NULL, 0, WDR_TIMEOUT) < 0) { if (ret < 0) dev_err(ddev, "urb failed to clear flow control\n"); dev_err(&port->dev, "failed to set flow control: %d\n", ret); } } } } } /* /* Loading