Re: [Ftdi-usb-sio-devel] Question about FlowControl.
Brought to you by:
bryder
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 > |