Skip to content

Commit e9ec225

Browse files
tmlindgregkh
authored andcommitted
tty: n_gsm: Fix long delays with control frame timeouts in ADM mode
Commit ea3d846 ("tty: n_gsm: Allow ADM response in addition to UA for control dlci") added support for DLCI to stay in Asynchronous Disconnected Mode (ADM). But we still get long delays waiting for commands to other DLCI to complete: --> 5) C: SABM(P) Q> 0) C: UIH(F) Q> 0) C: UIH(F) Q> 0) C: UIH(F) ... This happens because gsm_control_send() sets cretries timer to T2 that is by default set to 34. This will cause resend for T2 times for the control frame. In ADM mode, we will never get a response so the control frame, so retries are just delaying all the commands. Let's fix the issue by setting DLCI_MODE_ADM flag after detecting the ADM mode for the control DLCI. Then we can use that in gsm_control_send() to set retries to 1. This means the control frame will be sent once allowing the other end at an opportunity to switch from ADM to ABM mode. Note that retries will be decremented in gsm_control_retransmit() so we don't want to set it to 0 here. Fixes: ea3d846 ("tty: n_gsm: Allow ADM response in addition to UA for control dlci") Cc: [email protected] Cc: Alan Cox <[email protected]> Cc: Dan Williams <[email protected]> Cc: Jiri Prchal <[email protected]> Cc: Jiri Slaby <[email protected]> Cc: Marcel Partap <[email protected]> Cc: Merlijn Wajer <[email protected]> Cc: Michael Nazzareno Trimarchi <[email protected]> Cc: Michael Scott <[email protected]> Cc: Pavel Machek <[email protected]> Cc: Peter Hurley <[email protected]> Cc: Russ Gorby <[email protected]> Cc: Sascha Hauer <[email protected]> Cc: Sebastian Reichel <[email protected]> Signed-off-by: Tony Lindgren <[email protected]> Cc: stable <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 60cc43f commit e9ec225

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

drivers/tty/n_gsm.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ struct gsm_dlci {
121121
struct mutex mutex;
122122

123123
/* Link layer */
124+
int mode;
125+
#define DLCI_MODE_ABM 0 /* Normal Asynchronous Balanced Mode */
126+
#define DLCI_MODE_ADM 1 /* Asynchronous Disconnected Mode */
124127
spinlock_t lock; /* Protects the internal state */
125128
struct timer_list t1; /* Retransmit timer for SABM and UA */
126129
int retries;
@@ -1364,7 +1367,13 @@ static struct gsm_control *gsm_control_send(struct gsm_mux *gsm,
13641367
ctrl->data = data;
13651368
ctrl->len = clen;
13661369
gsm->pending_cmd = ctrl;
1367-
gsm->cretries = gsm->n2;
1370+
1371+
/* If DLCI0 is in ADM mode skip retries, it won't respond */
1372+
if (gsm->dlci[0]->mode == DLCI_MODE_ADM)
1373+
gsm->cretries = 1;
1374+
else
1375+
gsm->cretries = gsm->n2;
1376+
13681377
mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
13691378
gsm_control_transmit(gsm, ctrl);
13701379
spin_unlock_irqrestore(&gsm->control_lock, flags);
@@ -1472,6 +1481,7 @@ static void gsm_dlci_t1(struct timer_list *t)
14721481
if (debug & 8)
14731482
pr_info("DLCI %d opening in ADM mode.\n",
14741483
dlci->addr);
1484+
dlci->mode = DLCI_MODE_ADM;
14751485
gsm_dlci_open(dlci);
14761486
} else {
14771487
gsm_dlci_close(dlci);

0 commit comments

Comments
 (0)