diff options
Diffstat (limited to 'drivers/tty/n_gsm.c')
-rw-r--r-- | drivers/tty/n_gsm.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 5131bdc9e765..3b3e1f6632d7 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1451,6 +1451,10 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) * in which case an opening port goes back to closed and a closing port * is simply put into closed state (any further frames from the other * end will get a DM response) + * + * Some control dlci can stay in ADM mode with other dlci working just + * fine. In that case we can just keep the control dlci open after the + * DLCI_OPENING retries time out. */ static void gsm_dlci_t1(struct timer_list *t) @@ -1464,8 +1468,15 @@ static void gsm_dlci_t1(struct timer_list *t) if (dlci->retries) { gsm_command(dlci->gsm, dlci->addr, SABM|PF); mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); - } else + } else if (!dlci->addr && gsm->control == (DM | PF)) { + if (debug & 8) + pr_info("DLCI %d opening in ADM mode.\n", + dlci->addr); + gsm_dlci_open(dlci); + } else { gsm_dlci_close(dlci); + } + break; case DLCI_CLOSING: dlci->retries--; @@ -1483,8 +1494,8 @@ static void gsm_dlci_t1(struct timer_list *t) * @dlci: DLCI to open * * Commence opening a DLCI from the Linux side. We issue SABM messages - * to the modem which should then reply with a UA, at which point we - * will move into open state. Opening is done asynchronously with retry + * to the modem which should then reply with a UA or ADM, at which point + * we will move into open state. Opening is done asynchronously with retry * running off timers and the responses. */ @@ -2457,20 +2468,20 @@ static ssize_t gsmld_write(struct tty_struct *tty, struct file *file, * Called without the kernel lock held - fine */ -static unsigned int gsmld_poll(struct tty_struct *tty, struct file *file, +static __poll_t gsmld_poll(struct tty_struct *tty, struct file *file, poll_table *wait) { - unsigned int mask = 0; + __poll_t mask = 0; struct gsm_mux *gsm = tty->disc_data; poll_wait(file, &tty->read_wait, wait); poll_wait(file, &tty->write_wait, wait); if (tty_hung_up_p(file)) - mask |= POLLHUP; + mask |= EPOLLHUP; if (!tty_is_writelocked(tty) && tty_write_room(tty) > 0) - mask |= POLLOUT | POLLWRNORM; + mask |= EPOLLOUT | EPOLLWRNORM; if (gsm->dead) - mask |= POLLHUP; + mask |= EPOLLHUP; return mask; } @@ -2955,7 +2966,6 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) static void gsmtty_close(struct tty_struct *tty, struct file *filp) { struct gsm_dlci *dlci = tty->driver_data; - struct gsm_mux *gsm; if (dlci == NULL) return; @@ -2964,7 +2974,6 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) mutex_lock(&dlci->mutex); gsm_destroy_network(dlci); mutex_unlock(&dlci->mutex); - gsm = dlci->gsm; if (tty_port_close_start(&dlci->port, tty, filp) == 0) return; gsm_dlci_begin_close(dlci); |