Linux 3.10.86
[firefly-linux-kernel-4.4.55.git] / drivers / tty / n_gsm.c
index 4a43ef5d7962c9b043dc047ac16a5207f656bfa7..3ee7217e25b2d8d2b52815018d9cb40548e99dba 100644 (file)
@@ -1089,6 +1089,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen)
 {
        unsigned int addr = 0;
        unsigned int modem = 0;
+       unsigned int brk = 0;
        struct gsm_dlci *dlci;
        int len = clen;
        u8 *dp = data;
@@ -1115,6 +1116,16 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen)
                if (len == 0)
                        return;
        }
+       len--;
+       if (len > 0) {
+               while (gsm_read_ea(&brk, *dp++) == 0) {
+                       len--;
+                       if (len == 0)
+                               return;
+               }
+               modem <<= 7;
+               modem |= (brk & 0x7f);
+       }
        tty = tty_port_tty_get(&dlci->port);
        gsm_process_modem(tty, dlci, modem, clen);
        if (tty) {
@@ -1418,11 +1429,7 @@ static void gsm_dlci_close(struct gsm_dlci *dlci)
                pr_debug("DLCI %d goes closed.\n", dlci->addr);
        dlci->state = DLCI_CLOSED;
        if (dlci->addr != 0) {
-               struct tty_struct  *tty = tty_port_tty_get(&dlci->port);
-               if (tty) {
-                       tty_hangup(tty);
-                       tty_kref_put(tty);
-               }
+               tty_port_tty_hangup(&dlci->port, false);
                kfifo_reset(dlci->fifo);
        } else
                dlci->gsm->dead = 1;
@@ -2968,6 +2975,10 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp)
        if (tty_port_close_start(&dlci->port, tty, filp) == 0)
                goto out;
        gsm_dlci_begin_close(dlci);
+       if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) {
+               if (C_HUPCL(tty))
+                       tty_port_lower_dtr_rts(&dlci->port);
+       }
        tty_port_close_end(&dlci->port, tty);
        tty_port_tty_set(&dlci->port, NULL);
 out: