Skip to content

Commit 75417d9

Browse files
Frank Schäfergregkh
authored andcommitted
usb: pl2303: do not round to the next nearest standard baud rate for the divisor based baud rate encoding method
In opposition to the direct baud rate encoding method, the divisor based method is not limited to a fixed set of standard baud rates. Hence, there is no need to round to the next nearest standard value. Reported-by: Mastro Gippo <[email protected]> Signed-off-by: Frank Schäfer <[email protected]> Signed-off-by: Reinhard Max <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 57ce61a commit 75417d9

File tree

1 file changed

+37
-28
lines changed

1 file changed

+37
-28
lines changed

drivers/usb/serial/pl2303.c

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -273,44 +273,46 @@ static void pl2303_encode_baudrate(struct tty_struct *tty,
273273
struct usb_serial_port *port,
274274
u8 buf[4])
275275
{
276-
const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600,
277-
4800, 7200, 9600, 14400, 19200, 28800, 38400,
278-
57600, 115200, 230400, 460800, 500000, 614400,
279-
921600, 1228800, 2457600, 3000000, 6000000 };
280-
281276
struct usb_serial *serial = port->serial;
282277
struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
283278
int baud;
284-
int i;
285279

286-
/*
287-
* NOTE: Only the values defined in baud_sup are supported!
288-
* => if unsupported values are set, the PL2303 seems to use
289-
* 9600 baud (at least my PL2303X always does)
290-
*/
291280
baud = tty_get_baud_rate(tty);
292281
dev_dbg(&port->dev, "baud requested = %d\n", baud);
293282
if (!baud)
294283
return;
295284

296-
/* Set baudrate to nearest supported value */
297-
for (i = 0; i < ARRAY_SIZE(baud_sup); ++i) {
298-
if (baud_sup[i] > baud)
299-
break;
300-
}
285+
if (spriv->type != HX || baud <= 115200) {
286+
/*
287+
* NOTE: Only the values defined in baud_sup are supported !
288+
* => if unsupported values are set, the PL2303 seems to
289+
* use 9600 baud (at least my PL2303X always does)
290+
*/
291+
const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400,
292+
3600, 4800, 7200, 9600, 14400, 19200,
293+
28800, 38400, 57600, 115200, 230400,
294+
460800, 500000, 614400, 921600,
295+
1228800, 2457600, 3000000, 6000000 };
296+
int i;
297+
298+
/* Set baudrate to nearest supported value */
299+
for (i = 0; i < ARRAY_SIZE(baud_sup); ++i) {
300+
if (baud_sup[i] > baud)
301+
break;
302+
}
301303

302-
if (i == ARRAY_SIZE(baud_sup))
303-
baud = baud_sup[i - 1];
304-
else if (i > 0 && (baud_sup[i] - baud) > (baud - baud_sup[i - 1]))
305-
baud = baud_sup[i - 1];
306-
else
307-
baud = baud_sup[i];
304+
if (i == ARRAY_SIZE(baud_sup))
305+
baud = baud_sup[i - 1];
306+
else if (i > 0
307+
&& (baud_sup[i] - baud) > (baud - baud_sup[i - 1]))
308+
baud = baud_sup[i - 1];
309+
else
310+
baud = baud_sup[i];
308311

309-
/* type_0, type_1 only support up to 1228800 baud */
310-
if (spriv->type != HX)
311-
baud = min_t(int, baud, 1228800);
312+
/* type_0, type_1 only support up to 1228800 baud */
313+
if (spriv->type != HX)
314+
baud = min_t(int, baud, 1228800);
312315

313-
if (spriv->type != HX || baud <= 115200) {
314316
/* Direct (standard) baud rate encoding method */
315317
put_unaligned_le32(baud, buf);
316318
} else {
@@ -331,10 +333,17 @@ static void pl2303_encode_baudrate(struct tty_struct *tty,
331333
* => 8 < B < 16: device seems to work not properly
332334
* => B <= 8: device uses the max. value B = 512 instead
333335
*/
336+
unsigned int A, B;
334337

338+
/* Respect the specified baud rate limits */
339+
baud = max_t(int, baud, 75);
340+
if (spriv->type == HX)
341+
baud = min_t(int, baud, 6000000);
342+
else
343+
baud = min_t(int, baud, 1228800);
335344
/* Determine factors A and B */
336-
unsigned int A = 0;
337-
unsigned int B = 12000000 * 32 / baud; /* 12MHz */
345+
A = 0;
346+
B = 12000000 * 32 / baud; /* 12MHz */
338347
B <<= 1; /* Add one bit for rounding */
339348
while (B > (512 << 1) && A <= 14) {
340349
A += 2;

0 commit comments

Comments
 (0)