]> git.hungrycats.org Git - linux/commitdiff
[SERIAL] Restrict the baud rates returnable from uart_get_baud_rate()
authorRussell King <rmk@flint.arm.linux.org.uk>
Wed, 8 Jan 2003 23:21:39 +0000 (23:21 +0000)
committerRussell King <rmk@flint.arm.linux.org.uk>
Wed, 8 Jan 2003 23:21:39 +0000 (23:21 +0000)
Supply the old termios, along with the max and min acceptable baud
rate to uart_get_baud_rate().  uart_get_baud_rate() will now try to
find a baud rate that satisfies the max and min constraint out of
(requested rate, old rate, 9600 baud).

We remove the code which performed a similar act in uart_get_divisor()
and pass an appropriate min and max baud rate to uart_get_baud_rate()
based on the UART clock rate.

drivers/serial/core.c
include/linux/serial_core.h

index 4d6d0e72954bd0e6a0455414f2c73f8888fc2ac0..02bc772404196b63cb17708f4a1ec1edbb00a3ac 100644 (file)
@@ -314,40 +314,68 @@ EXPORT_SYMBOL(uart_update_timeout);
  *     uart_get_baud_rate - return baud rate for a particular port
  *     @port: uart_port structure describing the port in question.
  *     @termios: desired termios settings.
+ *     @old: old termios (or NULL)
+ *     @min: minimum acceptable baud rate
+ *     @max: maximum acceptable baud rate
  *
  *     Decode the termios structure into a numeric baud rate,
  *     taking account of the magic 38400 baud rate (with spd_*
  *     flags), and mapping the %B0 rate to 9600 baud.
  */
 unsigned int
-uart_get_baud_rate(struct uart_port *port, struct termios *termios)
+uart_get_baud_rate(struct uart_port *port, struct termios *termios,
+                  struct termios *old, unsigned int min, unsigned int max)
 {
-       unsigned int baud = tty_termios_baud_rate(termios);
+       unsigned int try, baud, altbaud = 38400;
+       unsigned int flags = port->flags & UPF_SPD_MASK;
 
-       /*
-        * The spd_hi, spd_vhi, spd_shi, spd_warp kludge...
-        * Die! Die! Die!
-        */
-       if (baud == 38400) {
-               unsigned int flags = port->flags & UPF_SPD_MASK;
-
-               if (flags == UPF_SPD_HI)
-                       baud = 57600;
-               if (flags == UPF_SPD_VHI)
-                       baud = 115200;
-               if (flags == UPF_SPD_SHI)
-                       baud = 230400;
-               if (flags == UPF_SPD_WARP)
-                       baud = 460800;
-       }
+       if (flags == UPF_SPD_HI)
+               altbaud = 57600;
+       if (flags == UPF_SPD_VHI)
+               altbaud = 115200;
+       if (flags == UPF_SPD_SHI)
+               altbaud = 230400;
+       if (flags == UPF_SPD_WARP)
+               altbaud = 460800;
 
-       /*
-        * Special case: B0 rate.
-        */
-       if (baud == 0)
-               baud = 9600;
+       for (try = 0; try < 2; try++) {
+               baud = tty_termios_baud_rate(termios);
+
+               /*
+                * The spd_hi, spd_vhi, spd_shi, spd_warp kludge...
+                * Die! Die! Die!
+                */
+               if (baud == 38400)
+                       baud = altbaud;
+
+               /*
+                * Special case: B0 rate.
+                */
+               if (baud == 0)
+                       baud = 9600;
+
+               if (baud >= min && baud <= max)
+                       return baud;
+
+               /*
+                * Oops, the quotient was zero.  Try again with
+                * the old baud rate if possible.
+                */
+               termios->c_cflag &= ~CBAUD;
+               if (old) {
+                       termios->c_cflag |= old->c_cflag & CBAUD;
+                       old = NULL;
+                       continue;
+               }
 
-       return baud;
+               /*
+                * As a last resort, if the quotient is zero,
+                * default to 9600 bps
+                */
+               termios->c_cflag |= B9600;
+       }
+
+       return 0;
 }
 
 EXPORT_SYMBOL(uart_get_baud_rate);
@@ -355,16 +383,6 @@ EXPORT_SYMBOL(uart_get_baud_rate);
 static inline unsigned int
 uart_calculate_quot(struct uart_port *port, unsigned int baud)
 {
-       unsigned int quot;
-
-       /*
-        * Old custom speed handling.
-        */
-       if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
-               quot = port->custom_divisor;
-       else
-               quot = port->uartclk / (16 * baud);
-
        return quot;
 }
 
@@ -387,34 +405,18 @@ unsigned int
 uart_get_divisor(struct uart_port *port, struct termios *termios,
                 struct termios *old_termios)
 {
-       unsigned int quot, try;
+       unsigned int quot, baud, max = port->uartclk / 16;
 
-       for (try = 0; try < 3; try ++) {
-               unsigned int baud;
-
-               /* Determine divisor based on baud rate */
-               baud = uart_get_baud_rate(port, termios);
-               quot = uart_calculate_quot(port, baud);
-               if (quot)
-                       return quot;
-
-               /*
-                * Oops, the quotient was zero.  Try again with
-                * the old baud rate if possible.
-                */
-               termios->c_cflag &= ~CBAUD;
-               if (old_termios) {
-                       termios->c_cflag |= old_termios->c_cflag & CBAUD;
-                       old_termios = NULL;
-                       continue;
-               }
+       /* Determine divisor based on baud rate */
+       baud = uart_get_baud_rate(port, termios, old_termios, 0, max);
 
-               /*
-                * As a last resort, if the quotient is zero,
-                * default to 9600 bps
-                */
-               termios->c_cflag |= B9600;
-       }
+       /*
+        * Old custom speed handling.
+        */
+       if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
+               quot = port->custom_divisor;
+       else
+               quot = port->uartclk / (16 * baud);
 
        return quot;
 }
index 58fe38afbd8ed6bf3706ca2d5a9855ee62481eea..41b764e48f773d5f3130d370e2fdc0def3957eef 100644 (file)
@@ -280,8 +280,9 @@ void uart_write_wakeup(struct uart_port *port);
  */
 void uart_update_timeout(struct uart_port *port, unsigned int cflag,
                         unsigned int quot);
-unsigned int uart_get_baud_rate(struct uart_port *port,
-                               struct termios *termios);
+unsigned int uart_get_baud_rate(struct uart_port *port, struct termios *termios
+                               struct termios *old, unsigned int min,
+                               unsigned int max);
 unsigned int uart_get_divisor(struct uart_port *port, struct termios *termios,
                              struct termios *old_termios);