The driver wasn't properly configuring the hardware for the current
termios settings under all conditions.  Ensure that termios are
written to the device when the port is activated.

Signed-off-by: Jim Paris <j...@jtan.com>
---

Peter Hurley wrote:
> Yeah, you're right that the cdc-acm driver isn't properly configuring
> the hardware for the current termios settings under all conditions.
> 
> But you don't want to do it for every tty open, only for opens
> requiring port initialization, which is what the tty_port->activate()
> method is for (ie., acm_port_activate()).

I moved it to acm_port_activate(), which works fine.  Thanks!
acm_tty_set_termios is just moved in this patch, not changed.

Jim

---
 drivers/usb/class/cdc-acm.c | 104 ++++++++++++++++++++++----------------------
 1 file changed, 53 insertions(+), 51 deletions(-)

diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index e934e19f49f5..24077deb737a 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -504,6 +504,57 @@ static int acm_tty_open(struct tty_struct *tty, struct 
file *filp)
        return tty_port_open(&acm->port, tty, filp);
 }
 
+static void acm_tty_set_termios(struct tty_struct *tty,
+                                               struct ktermios *termios_old)
+{
+       struct acm *acm = tty->driver_data;
+       struct ktermios *termios = &tty->termios;
+       struct usb_cdc_line_coding newline;
+       int newctrl = acm->ctrlout;
+
+       newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty));
+       newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0;
+       newline.bParityType = termios->c_cflag & PARENB ?
+                               (termios->c_cflag & PARODD ? 1 : 2) +
+                               (termios->c_cflag & CMSPAR ? 2 : 0) : 0;
+       switch (termios->c_cflag & CSIZE) {
+       case CS5:
+               newline.bDataBits = 5;
+               break;
+       case CS6:
+               newline.bDataBits = 6;
+               break;
+       case CS7:
+               newline.bDataBits = 7;
+               break;
+       case CS8:
+       default:
+               newline.bDataBits = 8;
+               break;
+       }
+       /* FIXME: Needs to clear unsupported bits in the termios */
+       acm->clocal = ((termios->c_cflag & CLOCAL) != 0);
+
+       if (!newline.dwDTERate) {
+               newline.dwDTERate = acm->line.dwDTERate;
+               newctrl &= ~ACM_CTRL_DTR;
+       } else
+               newctrl |=  ACM_CTRL_DTR;
+
+       if (newctrl != acm->ctrlout)
+               acm_set_control(acm, acm->ctrlout = newctrl);
+
+       if (memcmp(&acm->line, &newline, sizeof newline)) {
+               memcpy(&acm->line, &newline, sizeof newline);
+               dev_dbg(&acm->control->dev, "%s - set line: %d %d %d %d\n",
+                       __func__,
+                       le32_to_cpu(newline.dwDTERate),
+                       newline.bCharFormat, newline.bParityType,
+                       newline.bDataBits);
+               acm_set_line(acm, &acm->line);
+       }
+}
+
 static void acm_port_dtr_rts(struct tty_port *port, int raise)
 {
        struct acm *acm = container_of(port, struct acm, port);
@@ -554,6 +605,8 @@ static int acm_port_activate(struct tty_port *port, struct 
tty_struct *tty)
                goto error_submit_urb;
        }
 
+       acm_tty_set_termios(tty, NULL);
+
        /*
         * Unthrottle device in case the TTY was closed while throttled.
         */
@@ -949,57 +1002,6 @@ static int acm_tty_ioctl(struct tty_struct *tty,
        return rv;
 }
 
-static void acm_tty_set_termios(struct tty_struct *tty,
-                                               struct ktermios *termios_old)
-{
-       struct acm *acm = tty->driver_data;
-       struct ktermios *termios = &tty->termios;
-       struct usb_cdc_line_coding newline;
-       int newctrl = acm->ctrlout;
-
-       newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty));
-       newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0;
-       newline.bParityType = termios->c_cflag & PARENB ?
-                               (termios->c_cflag & PARODD ? 1 : 2) +
-                               (termios->c_cflag & CMSPAR ? 2 : 0) : 0;
-       switch (termios->c_cflag & CSIZE) {
-       case CS5:
-               newline.bDataBits = 5;
-               break;
-       case CS6:
-               newline.bDataBits = 6;
-               break;
-       case CS7:
-               newline.bDataBits = 7;
-               break;
-       case CS8:
-       default:
-               newline.bDataBits = 8;
-               break;
-       }
-       /* FIXME: Needs to clear unsupported bits in the termios */
-       acm->clocal = ((termios->c_cflag & CLOCAL) != 0);
-
-       if (!newline.dwDTERate) {
-               newline.dwDTERate = acm->line.dwDTERate;
-               newctrl &= ~ACM_CTRL_DTR;
-       } else
-               newctrl |=  ACM_CTRL_DTR;
-
-       if (newctrl != acm->ctrlout)
-               acm_set_control(acm, acm->ctrlout = newctrl);
-
-       if (memcmp(&acm->line, &newline, sizeof newline)) {
-               memcpy(&acm->line, &newline, sizeof newline);
-               dev_dbg(&acm->control->dev, "%s - set line: %d %d %d %d\n",
-                       __func__,
-                       le32_to_cpu(newline.dwDTERate),
-                       newline.bCharFormat, newline.bParityType,
-                       newline.bDataBits);
-               acm_set_line(acm, &acm->line);
-       }
-}
-
 static const struct tty_port_operations acm_port_ops = {
        .dtr_rts = acm_port_dtr_rts,
        .shutdown = acm_port_shutdown,
-- 
2.1.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to