tty: n_gsm: Fix long delays with control frame timeouts in ADM mode
[muen/linux.git] / drivers / tty / n_gsm.c
index 3b3e1f6632d71c1aae24d690679b4b53673ce148..7b1f8636f8e9b44690f68b4f03cf0c722ea30d41 100644 (file)
@@ -121,6 +121,9 @@ struct gsm_dlci {
        struct mutex mutex;
 
        /* Link layer */
+       int mode;
+#define DLCI_MODE_ABM          0       /* Normal Asynchronous Balanced Mode */
+#define DLCI_MODE_ADM          1       /* Asynchronous Disconnected Mode */
        spinlock_t lock;        /* Protects the internal state */
        struct timer_list t1;   /* Retransmit timer for SABM and UA */
        int retries;
@@ -1364,7 +1367,13 @@ retry:
        ctrl->data = data;
        ctrl->len = clen;
        gsm->pending_cmd = ctrl;
-       gsm->cretries = gsm->n2;
+
+       /* If DLCI0 is in ADM mode skip retries, it won't respond */
+       if (gsm->dlci[0]->mode == DLCI_MODE_ADM)
+               gsm->cretries = 1;
+       else
+               gsm->cretries = gsm->n2;
+
        mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
        gsm_control_transmit(gsm, ctrl);
        spin_unlock_irqrestore(&gsm->control_lock, flags);
@@ -1472,6 +1481,7 @@ static void gsm_dlci_t1(struct timer_list *t)
                        if (debug & 8)
                                pr_info("DLCI %d opening in ADM mode.\n",
                                        dlci->addr);
+                       dlci->mode = DLCI_MODE_ADM;
                        gsm_dlci_open(dlci);
                } else {
                        gsm_dlci_close(dlci);