Re: ftdi_sio bug: setting two custom baud rates in a row fails

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

When setting custom baud rates with the ftdi_sio module using "method
#3" (setting the custom_divisor via TIOCSSERIAL), subsequent changes
to *another custom baud rate* do not  take effect.  For example, if I
change from baud rate 460800 (a "standard" rate) to 500000 (a custom
rate), it works fine. If I then go directly to 1M baud, I stay at
500000 baud. If I go from 460800->500000->38400->1M, I reach 1M
correctly as well. Summary: it seems that transitioning from a
standard to a custom baud rate works; transitioning from one custom
baud rate to another does not (you stay in the old custom baud).

Here is a syslog showing the failure. The lines marked "setting baud"
are from my application so that we can see where each baud-setting
operation begins. Each operation includes a call to TIOCGSERIAL

[271243.499635] setting baud 460800
[271243.499701] ftdi_sio ttyUSB0: get_ftdi_divisor - tty_get_baud_rate
reports speed 460800
[271243.499704] ftdi_sio ttyUSB0: get_ftdi_divisor - Baud rate set to
460800 (divisor 0x4006) on chip FT232RL
[271243.503172] ftdi_sio ttyUSB0: ftdi_set_termios Turning off
hardware flow control
[271243.507837] ftdi_sio ttyUSB0: write_latency_timer: setting latency timer = 1
[271243.512342] ftdi_sio ttyUSB0: get_ftdi_divisor - tty_get_baud_rate
reports speed 460800
[271243.512345] ftdi_sio ttyUSB0: get_ftdi_divisor - Baud rate set to
460800 (divisor 0x4006) on chip FT232RL
[271243.580422] setting baud 500000
[271243.580470] ftdi_sio ttyUSB0: get_ftdi_divisor - tty_get_baud_rate
reports speed 38400
[271243.580473] ftdi_sio ttyUSB0: get_ftdi_divisor - Baud rate set to
38400 (divisor 0xC04E) on chip FT232RL
[271243.583731] ftdi_sio ttyUSB0: ftdi_set_termios Turning off
hardware flow control
[271243.588774] ftdi_sio ttyUSB0: write_latency_timer: setting latency timer = 1
[271243.593480] ftdi_sio ttyUSB0: get_ftdi_divisor - tty_get_baud_rate
reports speed 38400
[271243.593484] ftdi_sio ttyUSB0: get_ftdi_divisor - custom divisor 48
sets baud rate to 500000  (<<<<<<<< NOTE)
[271243.593486] ftdi_sio ttyUSB0: get_ftdi_divisor - Baud rate set to
500000 (divisor 0x6) on chip FT232RL
[271243.661457] setting baud 1000000
[271243.661500] ftdi_sio ttyUSB0: get_ftdi_divisor - tty_get_baud_rate
reports speed 38400
[271243.661502] ftdi_sio ttyUSB0: get_ftdi_divisor - custom divisor 48
sets baud rate to 500000
[271243.661504] ftdi_sio ttyUSB0: get_ftdi_divisor - Baud rate set to
500000 (divisor 0x6) on chip FT232RL
[271243.664801] ftdi_sio ttyUSB0: ftdi_set_termios Turning off
hardware flow control
[271243.669317] ftdi_sio ttyUSB0: write_latency_timer: setting latency timer = 1
[271243.673929] ftdi_sio ttyUSB0: get_ftdi_divisor - tty_get_baud_rate
reports speed 500000  (<<<<<<<< NOTE, no corresponding line)
[271243.673932] ftdi_sio ttyUSB0: get_ftdi_divisor - Baud rate set to
500000 (divisor 0x6) on chip FT232RL
[271243.744304] ftdi_sio ttyUSB0: ftdi_get_modem_status - 0xf160

I think the problem is ultimately that two separate syscalls are
required to change a custom baud rate: set the baud rate to 38400,
then set the custom divisor. If one has a custom baud rate already
set, and then you set the baud rate to B38400, the driver immediately
recomputes the baud rate (using the "old" custom divisor). In other
words, it looks like you're trying to set a "new" custom baud rate,
but using the old custom divider. When the application then tries to
set the custom divider, the ftdi_sio driver sees that the baud rate
isn't 38400 and so ignores it. This logic is near line 1271:

1271 if (baud == 38400 &&
1272             ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) &&
1273              (priv->custom_divisor)) {
1274                 baud = priv->baud_base / priv->custom_divisor;
1275                 dev_dbg(dev, "%s - custom divisor %d sets baud
rate to %d\n",
1276                         __func__, priv->custom_divisor, baud);

I think that a reasonable solution is to remove the condition that baud==38400.

A tested work-around from user space is to first clear the
custom_divisor, then set 38400 baud, then reset the custom divisor.

I apologize that I'm not able to send a patch at this time.

Best,

-Ed

--
Edwin Olson
Assoc. Professor, Computer Science & Engineering
University of Michigan
http://april.eecs.umich.edu
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux