aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Schaefer <schaefer.frank@gmx.net>2009-08-18 14:15:07 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:36 -0400
commit25b8286805e856c8c7fda127018e31032c918015 (patch)
treee95665d787347049bc728d96c2c169f329e8a4db
parente55c6d06fead7e58b7c597fd9afc46a88ef740e6 (diff)
USB-serial: pl2303: fix baud rate handling in case of unsupported values
According to the datasheets, the PL2303 supports a set of 25 baudrates. The baudrate is set as a 4 byte value directly. During my experiments with device 067b:2303 (PL2303X), I noticed that - the bridge-controller always uses 9600 baud if invalid/unsupported baud rate values are set - the baud rate value returned by usb_control_msg(..., GET_LINE_REQUEST, ...) does not reflect the actually used baudrate. Always the last set value is returned, even if it was invalid and not used by the controller. This patch fixes the following issues with the current code: 1.) make sure that only supported baudrates are set (are there any buggy chip revisions out there which don't "like" other values... ?). 2.) always set the baudrate to the next nearest supported baudrate. 3.) applications can now read back the resulting baudrate properly, because tty_encode_baud_rate(...) is now fed with the actually used baudrate. Signed-off-by: Frank Schaefer <schaefer.frank@gmx.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/serial/pl2303.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 4cbe59c4ae7f..82055b07e02c 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -528,6 +528,12 @@ static void pl2303_set_termios(struct tty_struct *tty,
528 int baud; 528 int baud;
529 int i; 529 int i;
530 u8 control; 530 u8 control;
531 const int baud_sup[] = { 75, 150, 300, 600, 1200, 1800, 2400, 3600,
532 4800, 7200, 9600, 14400, 19200, 28800, 38400,
533 57600, 115200, 230400, 460800, 614400,
534 921600, 1228800, 2457600, 3000000, 6000000 };
535 int baud_floor, baud_ceil;
536 int k;
531 537
532 dbg("%s - port %d", __func__, port->number); 538 dbg("%s - port %d", __func__, port->number);
533 539
@@ -573,9 +579,39 @@ static void pl2303_set_termios(struct tty_struct *tty,
573 dbg("%s - data bits = %d", __func__, buf[6]); 579 dbg("%s - data bits = %d", __func__, buf[6]);
574 } 580 }
575 581
582 /* For reference buf[0]:buf[3] baud rate value */
583 /* NOTE: Only the values defined in baud_sup are supported !
584 * => if unsupported values are set, the PL2303 seems to use
585 * 9600 baud (at least my PL2303X always does)
586 */
576 baud = tty_get_baud_rate(tty); 587 baud = tty_get_baud_rate(tty);
577 dbg("%s - baud = %d", __func__, baud); 588 dbg("%s - baud requested = %d", __func__, baud);
578 if (baud) { 589 if (baud) {
590 /* Set baudrate to nearest supported value */
591 for (k=0; k<ARRAY_SIZE(baud_sup); k++) {
592 if (baud_sup[k] / baud) {
593 baud_ceil = baud_sup[k];
594 if (k==0) {
595 baud = baud_ceil;
596 } else {
597 baud_floor = baud_sup[k-1];
598 if ((baud_ceil % baud)
599 > (baud % baud_floor))
600 baud = baud_floor;
601 else
602 baud = baud_ceil;
603 }
604 break;
605 }
606 }
607 if (baud > 1228800) {
608 /* type_0, type_1 only support up to 1228800 baud */
609 if (priv->type != HX)
610 baud = 1228800;
611 else if (baud > 6000000)
612 baud = 6000000;
613 }
614 dbg("%s - baud set = %d", __func__, baud);
579 buf[0] = baud & 0xff; 615 buf[0] = baud & 0xff;
580 buf[1] = (baud >> 8) & 0xff; 616 buf[1] = (baud >> 8) & 0xff;
581 buf[2] = (baud >> 16) & 0xff; 617 buf[2] = (baud >> 16) & 0xff;
@@ -648,7 +684,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
648 pl2303_vendor_write(0x0, 0x0, serial); 684 pl2303_vendor_write(0x0, 0x0, serial);
649 } 685 }
650 686
651 /* FIXME: Need to read back resulting baud rate */ 687 /* Save resulting baud rate */
652 if (baud) 688 if (baud)
653 tty_encode_baud_rate(tty, baud, baud); 689 tty_encode_baud_rate(tty, baud, baud);
654 690