1
0
mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2026-01-11 17:10:13 +00:00

USB: serial: belkin_sa: fix TIOCMBIS and TIOCMBIC

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>
This commit is contained in:
Johan Hovold 2025-10-22 17:26:33 +02:00
parent dcb6fa37fd
commit b6e0b30161

View 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;