struct cp210x_serial_private *priv = usb_get_serial_data(serial);
        u32 baud;
 
+       if (tty->termios.c_ospeed == 0)
+               return;
+
        /*
         * This maps the requested rate to the actual rate, a valid rate on
         * cp2102 or cp2103, or to an arbitrary rate in [1M, max_speed].
-        *
-        * NOTE: B0 is not implemented.
         */
        baud = clamp(tty->termios.c_ospeed, priv->min_speed, priv->max_speed);
 
                tty->termios.c_iflag &= ~(IXON | IXOFF);
        }
 
-       if (old_termios &&
+       if (tty->termios.c_ospeed != 0 &&
+                       old_termios && old_termios->c_ospeed != 0 &&
                        C_CRTSCTS(tty) == (old_termios->c_cflag & CRTSCTS) &&
                        I_IXON(tty) == (old_termios->c_iflag & IXON) &&
                        I_IXOFF(tty) == (old_termios->c_iflag & IXOFF) &&
 
        mutex_lock(&port_priv->mutex);
 
+       if (tty->termios.c_ospeed == 0) {
+               port_priv->dtr = false;
+               port_priv->rts = false;
+       } else if (old_termios && old_termios->c_ospeed == 0) {
+               port_priv->dtr = true;
+               port_priv->rts = true;
+       }
+
        ret = cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl,
                        sizeof(flow_ctl));
        if (ret)
        u16 bits;
        int ret;
 
-       if (old_termios && !cp210x_termios_change(&tty->termios, old_termios))
+       if (old_termios && !cp210x_termios_change(&tty->termios, old_termios) &&
+                       tty->termios.c_ospeed != 0)
                return;
 
        if (!old_termios || tty->termios.c_ospeed != old_termios->c_ospeed)