aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorLars Poeschel <poeschel@lemonage.de>2014-01-07 07:34:37 -0500
committerFugang Duan <b38611@freescale.com>2014-06-26 20:18:28 -0400
commit4df3d41c37e22da3af67862ce39ee551b7a0e7df (patch)
tree2875a0301eb80ad5dd30006968d585be17e33af2 /drivers/tty
parent4a0477021f03428f4d61a9be73638cbdf858dd17 (diff)
tty: n_gsm: Fix for modems with brk in modem status control
3GPP TS 07.10 states in section 5.4.6.3.7: "The length byte contains the value 2 or 3 ... depending on the break signal." The break byte is optional and if it is sent, the length is 3. In fact the driver was not able to work with modems that send this break byte in their modem status control message. If the modem just sends the break byte if it is really set, then weird things might happen. The code for deconding the modem status to the internal linux presentation in gsm_process_modem has already a big comment about this 2 or 3 byte length thing and it is already able to decode the brk, but the code calling the gsm_process_modem function in gsm_control_modem does not encode it and hand it over the right way. This patch fixes this. Without this fix if the modem sends the brk byte in it's modem status control message the driver will hang when opening a muxed channel. Signed-off-by: Lars Poeschel <poeschel@lemonage.de> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/n_gsm.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 642239015b46..3ee7217e25b2 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -1089,6 +1089,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen)
1089{ 1089{
1090 unsigned int addr = 0; 1090 unsigned int addr = 0;
1091 unsigned int modem = 0; 1091 unsigned int modem = 0;
1092 unsigned int brk = 0;
1092 struct gsm_dlci *dlci; 1093 struct gsm_dlci *dlci;
1093 int len = clen; 1094 int len = clen;
1094 u8 *dp = data; 1095 u8 *dp = data;
@@ -1115,6 +1116,16 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen)
1115 if (len == 0) 1116 if (len == 0)
1116 return; 1117 return;
1117 } 1118 }
1119 len--;
1120 if (len > 0) {
1121 while (gsm_read_ea(&brk, *dp++) == 0) {
1122 len--;
1123 if (len == 0)
1124 return;
1125 }
1126 modem <<= 7;
1127 modem |= (brk & 0x7f);
1128 }
1118 tty = tty_port_tty_get(&dlci->port); 1129 tty = tty_port_tty_get(&dlci->port);
1119 gsm_process_modem(tty, dlci, modem, clen); 1130 gsm_process_modem(tty, dlci, modem, clen);
1120 if (tty) { 1131 if (tty) {