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]

 



On Thu, Dec 31, 2015 at 04:38:29PM -0500, Edwin Olson wrote:
> 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).

Thanks for the report.

Note that using ASYNC_SPD_CUST to set a custom divisor has been
deprecated and you should be using using the TCSETS2 ioctl to set
non-standard baudrates instead.

> 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.

No, the custom divisor should only be used when the speed is set to
38400 so that part is correct.

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

Setting the new divisor and then requesting 38400 baud would also work.

The current behaviour was introduced back in 2007 by commit 669a6db1037e
("USB: ftd_sio: cleanups and updates for new termios work") which
started reporting back the actual baudrate used by updating the termios
structure. That had the side-effect of a custom-divisor change not
taking effect until 38400 baud was again requested.

We could consider restoring the pre-2007 behaviour of ASYNC_SPD_CUST,
but that would prevent us from detecting that the driver selected 9600
baud when an invalid divisor was requested.

I think we should just leave this unchanged. 

Thanks,
Johan
--
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