diff options
author | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-05-10 07:19:23 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-05-10 07:19:23 -0400 |
commit | 71db1cd7ff4ea3b525ae7d9c97633ea281b7d981 (patch) | |
tree | 53ff3b8ecfc2869ec919e3423d69e07ddfaddd9a /drivers/tty/n_gsm.c | |
parent | 7d95fb746c4eece67308f1642a666ea1ebdbd2cc (diff) | |
parent | 75bc37fefc4471e718ba8e651aa74673d4e0a9eb (diff) |
Merge tag 'v4.17-rc4' into patchwork
Linux 4.17-rc4
* tag 'v4.17-rc4': (920 commits)
Linux 4.17-rc4
KVM: x86: remove APIC Timer periodic/oneshot spikes
genksyms: fix typo in parse.tab.{c,h} generation rules
kbuild: replace hardcoded bison in cmd_bison_h with $(YACC)
gcc-plugins: fix build condition of SANCOV plugin
MAINTAINERS: Update Kbuild entry with a few paths
Revert "usb: host: ehci: Use dma_pool_zalloc()"
platform/x86: Kconfig: Fix dell-laptop dependency chain.
platform/x86: asus-wireless: Fix NULL pointer dereference
arm64: vgic-v2: Fix proxying of cpuif access
KVM: arm/arm64: vgic_init: Cleanup reference to process_maintenance
KVM: arm64: Fix order of vcpu_write_sys_reg() arguments
MAINTAINERS & files: Canonize the e-mails I use at files
media: imx-media-csi: Fix inconsistent IS_ERR and PTR_ERR
tools: power/acpi, revert to LD = gcc
bdi: Fix oops in wb_workfn()
RDMA/cma: Do not query GID during QP state transition to RTR
IB/mlx4: Fix integer overflow when calculating optimal MTT size
IB/hfi1: Fix memory leak in exception path in get_irq_affinity()
IB/{hfi1, rdmavt}: Fix memory leak in hfi1_alloc_devdata() upon failure
...
Diffstat (limited to 'drivers/tty/n_gsm.c')
-rw-r--r-- | drivers/tty/n_gsm.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 3b3e1f6632d7..1dbe27c9946c 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -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); @@ -2861,11 +2871,22 @@ static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk) static int gsm_carrier_raised(struct tty_port *port) { struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port); + struct gsm_mux *gsm = dlci->gsm; + /* Not yet open so no carrier info */ if (dlci->state != DLCI_OPEN) return 0; if (debug & 2) return 1; + + /* + * Basic mode with control channel in ADM mode may not respond + * to CMD_MSC at all and modem_rx is empty. + */ + if (gsm->encoding == 0 && gsm->dlci[0]->mode == DLCI_MODE_ADM && + !dlci->modem_rx) + return 1; + return dlci->modem_rx & TIOCM_CD; } |