Skip to content

Commit 91d35ec

Browse files
jhovoldVudentz
authored andcommitted
Bluetooth: rfcomm: fix modem control handling
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") Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
1 parent 751463c commit 91d35ec

1 file changed

Lines changed: 11 additions & 15 deletions

File tree

  • net/bluetooth/rfcomm

net/bluetooth/rfcomm/tty.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -643,8 +643,8 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
643643
tty_port_tty_hangup(&dev->port, true);
644644

645645
dev->modem_status =
646-
((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
647-
((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
646+
((v24_sig & RFCOMM_V24_RTC) ? TIOCM_DSR : 0) |
647+
((v24_sig & RFCOMM_V24_RTR) ? TIOCM_CTS : 0) |
648648
((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
649649
((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
650650
}
@@ -1055,10 +1055,14 @@ static void rfcomm_tty_hangup(struct tty_struct *tty)
10551055
static int rfcomm_tty_tiocmget(struct tty_struct *tty)
10561056
{
10571057
struct rfcomm_dev *dev = tty->driver_data;
1058+
struct rfcomm_dlc *dlc = dev->dlc;
1059+
u8 v24_sig;
10581060

10591061
BT_DBG("tty %p dev %p", tty, dev);
10601062

1061-
return dev->modem_status;
1063+
rfcomm_dlc_get_modem_status(dlc, &v24_sig);
1064+
1065+
return (v24_sig & (TIOCM_DTR | TIOCM_RTS)) | dev->modem_status;
10621066
}
10631067

10641068
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
10711075

10721076
rfcomm_dlc_get_modem_status(dlc, &v24_sig);
10731077

1074-
if (set & TIOCM_DSR || set & TIOCM_DTR)
1078+
if (set & TIOCM_DTR)
10751079
v24_sig |= RFCOMM_V24_RTC;
1076-
if (set & TIOCM_RTS || set & TIOCM_CTS)
1080+
if (set & TIOCM_RTS)
10771081
v24_sig |= RFCOMM_V24_RTR;
1078-
if (set & TIOCM_RI)
1079-
v24_sig |= RFCOMM_V24_IC;
1080-
if (set & TIOCM_CD)
1081-
v24_sig |= RFCOMM_V24_DV;
10821082

1083-
if (clear & TIOCM_DSR || clear & TIOCM_DTR)
1083+
if (clear & TIOCM_DTR)
10841084
v24_sig &= ~RFCOMM_V24_RTC;
1085-
if (clear & TIOCM_RTS || clear & TIOCM_CTS)
1085+
if (clear & TIOCM_RTS)
10861086
v24_sig &= ~RFCOMM_V24_RTR;
1087-
if (clear & TIOCM_RI)
1088-
v24_sig &= ~RFCOMM_V24_IC;
1089-
if (clear & TIOCM_CD)
1090-
v24_sig &= ~RFCOMM_V24_DV;
10911087

10921088
rfcomm_dlc_set_modem_status(dlc, v24_sig);
10931089

0 commit comments

Comments
 (0)