diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index a4df0a20f212..68276a7e62a0 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -339,6 +339,7 @@ struct gsm_mux { unsigned long bad_fcs; unsigned long malformed; unsigned long io_error; + unsigned long open_error; unsigned long bad_size; unsigned long unsupported; }; @@ -1730,25 +1731,32 @@ static void gsm_control_negotiation(struct gsm_mux *gsm, unsigned int cr, struct gsm_dlci *dlci; struct gsm_dlci_param_bits *params; - if (dlen < sizeof(struct gsm_dlci_param_bits)) + if (dlen < sizeof(struct gsm_dlci_param_bits)) { + gsm->open_error++; return; + } /* Invalid DLCI? */ params = (struct gsm_dlci_param_bits *)data; addr = FIELD_GET(PN_D_FIELD_DLCI, params->d_bits); - if (addr == 0 || addr >= NUM_DLCI || !gsm->dlci[addr]) + if (addr == 0 || addr >= NUM_DLCI || !gsm->dlci[addr]) { + gsm->open_error++; return; + } dlci = gsm->dlci[addr]; /* Too late for parameter negotiation? */ - if ((!cr && dlci->state == DLCI_OPENING) || dlci->state == DLCI_OPEN) + if ((!cr && dlci->state == DLCI_OPENING) || dlci->state == DLCI_OPEN) { + gsm->open_error++; return; + } /* Process the received parameters */ if (gsm_process_negotiation(gsm, addr, cr, params) != 0) { /* Negotiation failed. Close the link. */ if (debug & DBG_ERRORS) pr_info("%s PN failed\n", __func__); + gsm->open_error++; gsm_dlci_close(dlci); return; } @@ -1768,6 +1776,7 @@ static void gsm_control_negotiation(struct gsm_mux *gsm, unsigned int cr, } else { if (debug & DBG_ERRORS) pr_info("%s PN in invalid state\n", __func__); + gsm->open_error++; } } @@ -2221,6 +2230,7 @@ static void gsm_dlci_t1(struct timer_list *t) dlci->retries--; mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); } else { + gsm->open_error++; gsm_dlci_begin_close(dlci); /* prevent half open link */ } break; @@ -2236,6 +2246,7 @@ static void gsm_dlci_t1(struct timer_list *t) dlci->mode = DLCI_MODE_ADM; gsm_dlci_open(dlci); } else { + gsm->open_error++; gsm_dlci_begin_close(dlci); /* prevent half open link */ } @@ -2757,12 +2768,16 @@ static void gsm_queue(struct gsm_mux *gsm) switch (gsm->control) { case SABM|PF: - if (cr == 1) + if (cr == 1) { + gsm->open_error++; goto invalid; + } if (dlci == NULL) dlci = gsm_dlci_alloc(gsm, address); - if (dlci == NULL) + if (dlci == NULL) { + gsm->open_error++; return; + } if (dlci->dead) gsm_response(gsm, address, DM|PF); else {