[Ftdi-usb-sio-devel] Question about FlowControl.
Brought to you by:
bryder
From: Toan P. <tph...@gm...> - 2009-01-30 15:15:13
|
Bill, I have a question about flow control in the ftdi driver. I notice that when I use serial port without flow control, the ftdi driver still does some kind of flow control with the ftdi chip. This is found in the set_mctrl, clear_mctrl, and update_mctrl functions. Is there a documentation on how flow control is implemented in this driver? Also, in the function update_mctrl, when something goes bad you disconnect the usb device, as seen in the code below. I've been experiencing alot of disconnections at this point, maybe due to noise in the bus; but I've tried shorter cable length, and disconnection still happen. Would you please explain why we disconnect here, and how often we do flow control request with the chip? thank you. REFERENCE: --------------------------------------------------------------------------------- static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned int clear) { struct ftdi_private *priv = usb_get_serial_port_data(port); char *buf; unsigned urb_value; int rv; if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) { dbg("%s - DTR|RTS not being set|cleared", __FUNCTION__); return 0; /* no change */ } buf = kmalloc(1, GFP_NOIO); if (!buf) { return -ENOMEM; } clear &= ~set; /* 'set' takes precedence over 'clear' */ urb_value = 0; if (clear & TIOCM_DTR) urb_value |= FTDI_SIO_SET_DTR_LOW; if (clear & TIOCM_RTS) urb_value |= FTDI_SIO_SET_RTS_LOW; if (set & TIOCM_DTR) urb_value |= FTDI_SIO_SET_DTR_HIGH; if (set & TIOCM_RTS) urb_value |= FTDI_SIO_SET_RTS_HIGH; 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, urb_value, priv->interface, buf, 0, WDR_TIMEOUT); kfree(buf); if (rv < 0) { err("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", __FUNCTION__, (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged", (set & TIOCM_RTS) ? "HIGH" : (clear & TIOCM_RTS) ? "LOW" : "unchanged"); usb_disconnect(port); /* THIS IS WHERE I OFFEN GET DISCONNECTIONS, i AM NOT SURE WHAT WENT BAD, HOST CONTROLLER, HUB, DEVICE?*/ } else { dbg("%s - DTR %s, RTS %s", __FUNCTION__, (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged", (set & TIOCM_RTS) ? "HIGH" : (clear & TIOCM_RTS) ? "LOW" : "unchanged"); priv->last_dtr_rts = (priv->last_dtr_rts & ~clear) | set; } return rv; } |