]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
USB: serial: belkin_sa: fix TIOCMBIS and TIOCMBIC
authorJohan Hovold <johan@kernel.org>
Wed, 22 Oct 2025 15:26:33 +0000 (17:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 12 Dec 2025 17:40:19 +0000 (18:40 +0100)
commit b6e0b3016187446ddef9edac03cd9d544ac63f11 upstream.

Asserting or deasserting a modem control line using TIOCMBIS or TIOCMBIC
should not deassert any lines that are not in the mask.

Fix this long-standing regression dating back to 2003 when the
tiocmset() callback was introduced.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/serial/belkin_sa.c

index 44f5b58beec9222704f4335164e806e969471140..aa6b4c4ad5ecbeb46f62600d975b073afb48d81e 100644 (file)
@@ -435,7 +435,7 @@ static int belkin_sa_tiocmset(struct tty_struct *tty,
        struct belkin_sa_private *priv = usb_get_serial_port_data(port);
        unsigned long control_state;
        unsigned long flags;
-       int retval;
+       int retval = 0;
        int rts = 0;
        int dtr = 0;
 
@@ -452,26 +452,32 @@ static int belkin_sa_tiocmset(struct tty_struct *tty,
        }
        if (clear & TIOCM_RTS) {
                control_state &= ~TIOCM_RTS;
-               rts = 0;
+               rts = 1;
        }
        if (clear & TIOCM_DTR) {
                control_state &= ~TIOCM_DTR;
-               dtr = 0;
+               dtr = 1;
        }
 
        priv->control_state = control_state;
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       retval = BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, rts);
-       if (retval < 0) {
-               dev_err(&port->dev, "Set RTS error %d\n", retval);
-               goto exit;
+       if (rts) {
+               retval = BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST,
+                                       !!(control_state & TIOCM_RTS));
+               if (retval < 0) {
+                       dev_err(&port->dev, "Set RTS error %d\n", retval);
+                       goto exit;
+               }
        }
 
-       retval = BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, dtr);
-       if (retval < 0) {
-               dev_err(&port->dev, "Set DTR error %d\n", retval);
-               goto exit;
+       if (dtr) {
+               retval = BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST,
+                                       !!(control_state & TIOCM_DTR));
+               if (retval < 0) {
+                       dev_err(&port->dev, "Set DTR error %d\n", retval);
+                       goto exit;
+               }
        }
 exit:
        return retval;