Thread: [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; } |
From: Bill R. <bil...@gm...> - 2009-01-30 19:48:06
|
On Sat, Jan 31, 2009 at 4:15 AM, Toan Pham <tph...@gm...> wrote: > 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. i don't know about those functions. Ian Abbott implemented them. http://www.mail-archive.com/bk-...@vg.../msg07158.html Looks like using them can make a massive difference to performance. The best place to look will probably be the usb_serial stuff or further up the stack in the tty driver. > > > 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. I assume that if an error is seen the assumption is made that the usb connection needs to be dropped. You could try removing the usb_disconnect but to be careful I suggest you dig around and see which error codes returned by usb_control_msg you should and shouldn't drop the connection on. Of course be prepared for panics or something if you try this! > > > > > > 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; > } > > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by: > SourcForge Community > SourceForge wants to tell your story. > http://p.sf.net/sfu/sf-spreadtheword > _______________________________________________ > Ftdi-usb-sio-devel mailing list > Ftd...@li... > https://lists.sourceforge.net/lists/listinfo/ftdi-usb-sio-devel > |