From: Pali Rohár pali@kernel.org
The baud rate generating divisor is a 17-bit wide (14 bits integer part and 3 bits fractional part).
Example: base clock = 48 MHz requested baud rate = 180 Baud divisor = 48,000,000 / (16 * 180) = 0b100000100011010.101
In this case the MSB gets discarded because of the overflow, and the actually used divisor will be 0b100011010.101 = 282.625, resulting in baud rate 10615 Baud, instead of the requested 180 Baud.
The best possible thing to do in this case is to generate lowest possible baud rate (in the example it would be 183 Baud), by using maximum possible divisor.
In case of divisor overflow, use maximum possible divisor.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Pali Rohár pali@kernel.org Tested-by: Marek Behún kabel@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Cc: stable@vger.kernel.org --- drivers/usb/serial/ftdi_sio.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index b440d338a895..ea40f367e70c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1157,6 +1157,8 @@ static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base) int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud); if ((divisor3 & 0x7) == 7) divisor3++; /* round x.7/8 up to x+1 */ + if (divisor3 > GENMASK(16, 0)) + divisor3 = GENMASK(16, 0); divisor = divisor3 >> 3; divisor3 &= 0x7; if (divisor3 == 1) @@ -1181,6 +1183,8 @@ static u32 ftdi_232bm_baud_base_to_divisor(int baud, int base) u32 divisor; /* divisor shifted 3 bits to the left */ int divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud); + if (divisor3 > GENMASK(16, 0)) + divisor3 = GENMASK(16, 0); divisor = divisor3 >> 3; divisor |= (u32)divfrac[divisor3 & 0x7] << 14; /* Deal with special cases for highest baud rates. */ @@ -1204,6 +1208,8 @@ static u32 ftdi_2232h_baud_base_to_divisor(int baud, int base)
/* hi-speed baud rate is 10-bit sampling instead of 16-bit */ divisor3 = DIV_ROUND_CLOSEST(8 * base, 10 * baud); + if (divisor3 > GENMASK(16, 0)) + divisor3 = GENMASK(16, 0);
divisor = divisor3 >> 3; divisor |= (u32)divfrac[divisor3 & 0x7] << 14;
On Tue, Jul 12, 2022 at 01:53:00PM +0200, Marek Behún wrote:
From: Pali Rohár pali@kernel.org
The baud rate generating divisor is a 17-bit wide (14 bits integer part and 3 bits fractional part).
Example: base clock = 48 MHz requested baud rate = 180 Baud divisor = 48,000,000 / (16 * 180) = 0b100000100011010.101
In this case the MSB gets discarded because of the overflow, and the actually used divisor will be 0b100011010.101 = 282.625, resulting in baud rate 10615 Baud, instead of the requested 180 Baud.
The best possible thing to do in this case is to generate lowest possible baud rate (in the example it would be 183 Baud), by using maximum possible divisor.
Actually, the best way to handle this is to add a sanity check for the lowest supported check as you do in the next patch. That one makes this change superfluous.
In case of divisor overflow, use maximum possible divisor.
Johan
linux-stable-mirror@lists.linaro.org