diff options
author | Russ Gorby <russ.gorby@intel.com> | 2011-06-14 16:23:28 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-06-16 15:00:15 -0400 |
commit | 7263287af93db4d5cf324a30546f2143419b7900 (patch) | |
tree | bad1a6d8e473bb30ddd09aeea172b95e7c2b9d6f /drivers/tty/n_gsm.c | |
parent | 2872628680bad71a6734e7d379168f990a91cc09 (diff) |
tty: n_gsm: Fixed logic to decode break signal from modem status
The modem status can be one or 2 octets and contains the V.24 signals
and in the 2 octet case also the break signal.
We were improperly decoding the break signal from the modem in the
2 octet case.
Signed-off-by: Russ Gorby <russ.gorby@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty/n_gsm.c')
-rw-r--r-- | drivers/tty/n_gsm.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 09e8c7d53af3..7290394e3131 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -984,10 +984,22 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, u8 *data, | |||
984 | */ | 984 | */ |
985 | 985 | ||
986 | static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | 986 | static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, |
987 | u32 modem) | 987 | u32 modem, int clen) |
988 | { | 988 | { |
989 | int mlines = 0; | 989 | int mlines = 0; |
990 | u8 brk = modem >> 6; | 990 | u8 brk = 0; |
991 | |||
992 | /* The modem status command can either contain one octet (v.24 signals) | ||
993 | or two octets (v.24 signals + break signals). The length field will | ||
994 | either be 2 or 3 respectively. This is specified in section | ||
995 | 5.4.6.3.7 of the 27.010 mux spec. */ | ||
996 | |||
997 | if (clen == 2) | ||
998 | modem = modem & 0x7f; | ||
999 | else { | ||
1000 | brk = modem & 0x7f; | ||
1001 | modem = (modem >> 7) & 0x7f; | ||
1002 | }; | ||
991 | 1003 | ||
992 | /* Flow control/ready to communicate */ | 1004 | /* Flow control/ready to communicate */ |
993 | if (modem & MDM_FC) { | 1005 | if (modem & MDM_FC) { |
@@ -1061,7 +1073,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen) | |||
1061 | return; | 1073 | return; |
1062 | } | 1074 | } |
1063 | tty = tty_port_tty_get(&dlci->port); | 1075 | tty = tty_port_tty_get(&dlci->port); |
1064 | gsm_process_modem(tty, dlci, modem); | 1076 | gsm_process_modem(tty, dlci, modem, clen); |
1065 | if (tty) { | 1077 | if (tty) { |
1066 | tty_wakeup(tty); | 1078 | tty_wakeup(tty); |
1067 | tty_kref_put(tty); | 1079 | tty_kref_put(tty); |
@@ -1482,12 +1494,13 @@ static void gsm_dlci_begin_close(struct gsm_dlci *dlci) | |||
1482 | * open we shovel the bits down it, if not we drop them. | 1494 | * open we shovel the bits down it, if not we drop them. |
1483 | */ | 1495 | */ |
1484 | 1496 | ||
1485 | static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len) | 1497 | static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int clen) |
1486 | { | 1498 | { |
1487 | /* krefs .. */ | 1499 | /* krefs .. */ |
1488 | struct tty_port *port = &dlci->port; | 1500 | struct tty_port *port = &dlci->port; |
1489 | struct tty_struct *tty = tty_port_tty_get(port); | 1501 | struct tty_struct *tty = tty_port_tty_get(port); |
1490 | unsigned int modem = 0; | 1502 | unsigned int modem = 0; |
1503 | int len = clen; | ||
1491 | 1504 | ||
1492 | if (debug & 16) | 1505 | if (debug & 16) |
1493 | pr_debug("%d bytes for tty %p\n", len, tty); | 1506 | pr_debug("%d bytes for tty %p\n", len, tty); |
@@ -1507,7 +1520,7 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len) | |||
1507 | if (len == 0) | 1520 | if (len == 0) |
1508 | return; | 1521 | return; |
1509 | } | 1522 | } |
1510 | gsm_process_modem(tty, dlci, modem); | 1523 | gsm_process_modem(tty, dlci, modem, clen); |
1511 | /* Line state will go via DLCI 0 controls only */ | 1524 | /* Line state will go via DLCI 0 controls only */ |
1512 | case 1: | 1525 | case 1: |
1513 | default: | 1526 | default: |