[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <9778a6a1-ffb0-4972-a2e7-893128a51e52@molgen.mpg.de>
Date: Wed, 29 Oct 2025 21:15:28 +0100
From: Paul Menzel <pmenzel@...gen.mpg.de>
To: Johan Hovold <johan@...nel.org>
Cc: Luiz Augusto von Dentz <luiz.dentz@...il.com>,
 Marcel Holtmann <marcel@...tmann.org>,
 Johan Hedberg <johan.hedberg@...il.com>, linux-bluetooth@...r.kernel.org,
 linux-kernel@...r.kernel.org, stable@...r.kernel.org
Subject: Re: [PATCH v2] Bluetooth: rfcomm: fix modem control handling
Dear Johan,
Thank you for your patch.
Am 23.10.25 um 14:05 schrieb Johan Hovold:
> The RFCOMM driver confuses the local and remote modem control signals,
> which specifically means that the reported DTR and RTS state will
> instead reflect the remote end (i.e. DSR and CTS).
> 
> This issue dates back to the original driver (and a follow-on update)
> merged in 2002, which resulted in a non-standard implementation of
> TIOCMSET that allowed controlling also the TS07.10 IC and DV signals by
> mapping them to the RI and DCD input flags, while TIOCMGET failed to
> return the actual state of DTR and RTS.
> 
> Note that the bogus control of input signals in tiocmset() is just
> dead code as those flags will have been masked out by the tty layer
> since 2003.
> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
There is a linux-history git archive [1], if somebody wants dig further. 
But not relevant for the tag used by the stable folks.
Is there any way to test your change, to read DTR and RTS state?
> Cc: stable@...r.kernel.org
> Signed-off-by: Johan Hovold <johan@...nel.org>
> ---
> 
> Changes in v2
>   - fix a compilation issue discovered before sending v1 but never folded
>     into the actual patch...
> 
> 
>   net/bluetooth/rfcomm/tty.c | 26 +++++++++++---------------
>   1 file changed, 11 insertions(+), 15 deletions(-)
> 
> diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
> index 376ce6de84be..b783526ab588 100644
> --- a/net/bluetooth/rfcomm/tty.c
> +++ b/net/bluetooth/rfcomm/tty.c
> @@ -643,8 +643,8 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
>   		tty_port_tty_hangup(&dev->port, true);
>   
>   	dev->modem_status =
> -		((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
> -		((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
> +		((v24_sig & RFCOMM_V24_RTC) ? TIOCM_DSR : 0) |
> +		((v24_sig & RFCOMM_V24_RTR) ? TIOCM_CTS : 0) |
>   		((v24_sig & RFCOMM_V24_IC)  ? TIOCM_RI : 0) |
>   		((v24_sig & RFCOMM_V24_DV)  ? TIOCM_CD : 0);
>   }
> @@ -1055,10 +1055,14 @@ static void rfcomm_tty_hangup(struct tty_struct *tty)
>   static int rfcomm_tty_tiocmget(struct tty_struct *tty)
>   {
>   	struct rfcomm_dev *dev = tty->driver_data;
> +	struct rfcomm_dlc *dlc = dev->dlc;
> +	u8 v24_sig;
>   
>   	BT_DBG("tty %p dev %p", tty, dev);
>   
> -	return dev->modem_status;
> +	rfcomm_dlc_get_modem_status(dlc, &v24_sig);
> +
> +	return (v24_sig & (TIOCM_DTR | TIOCM_RTS)) | dev->modem_status;
>   }
>   
>   static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
> @@ -1071,23 +1075,15 @@ static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigne
>   
>   	rfcomm_dlc_get_modem_status(dlc, &v24_sig);
>   
> -	if (set & TIOCM_DSR || set & TIOCM_DTR)
> +	if (set & TIOCM_DTR)
>   		v24_sig |= RFCOMM_V24_RTC;
> -	if (set & TIOCM_RTS || set & TIOCM_CTS)
> +	if (set & TIOCM_RTS)
>   		v24_sig |= RFCOMM_V24_RTR;
> -	if (set & TIOCM_RI)
> -		v24_sig |= RFCOMM_V24_IC;
> -	if (set & TIOCM_CD)
> -		v24_sig |= RFCOMM_V24_DV;
>   
> -	if (clear & TIOCM_DSR || clear & TIOCM_DTR)
> +	if (clear & TIOCM_DTR)
>   		v24_sig &= ~RFCOMM_V24_RTC;
> -	if (clear & TIOCM_RTS || clear & TIOCM_CTS)
> +	if (clear & TIOCM_RTS)
>   		v24_sig &= ~RFCOMM_V24_RTR;
> -	if (clear & TIOCM_RI)
> -		v24_sig &= ~RFCOMM_V24_IC;
> -	if (clear & TIOCM_CD)
> -		v24_sig &= ~RFCOMM_V24_DV;
>   
>   	rfcomm_dlc_set_modem_status(dlc, v24_sig);
>   
Kind regards,
Paul
[1]: 
https://web.git.kernel.org/pub/scm/linux/kernel/git/history/history.git/
Powered by blists - more mailing lists
 
