* [PATCH] tty: n_gsm: Don't block input queue by waiting MSC
@ 2025-08-25 13:55 Seppo Takalo
2025-08-26 7:08 ` Greg Kroah-Hartman
0 siblings, 1 reply; 3+ messages in thread
From: Seppo Takalo @ 2025-08-25 13:55 UTC (permalink / raw)
To: Greg Kroah-Hartman, linux-serial, linux-kernel; +Cc: Seppo Takalo
Add parameter "wait" for gsm_modem_update() to indicate if we
should wait for the response.
Currently gsm_queue() processes incoming frames and when opening
a DLC channel it calls gsm_dlci_open() which calls gsm_modem_update().
If basic mode is used it calls gsm_modem_upd_via_msc() and it
cannot block the input queue by waiting the response to come
into the same input queue.
Instead allow sending Modem Status Command without waiting for remote
end to respond.
Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
---
drivers/tty/n_gsm.c | 33 +++++++++++++++++++--------------
1 file changed, 19 insertions(+), 14 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 8dd3f23af3d2..8e8475d9fbeb 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -454,7 +454,7 @@ static const u8 gsm_fcs8[256] = {
static void gsm_dlci_close(struct gsm_dlci *dlci);
static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len);
-static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk);
+static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk, bool wait);
static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
u8 ctrl);
static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg);
@@ -2174,7 +2174,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
pr_debug("DLCI %d goes open.\n", dlci->addr);
/* Send current modem state */
if (dlci->addr) {
- gsm_modem_update(dlci, 0);
+ gsm_modem_update(dlci, 0, false);
} else {
/* Start keep-alive control */
gsm->ka_num = 0;
@@ -4138,7 +4138,7 @@ static void gsm_modem_upd_via_data(struct gsm_dlci *dlci, u8 brk)
* @brk: break signal
*/
-static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk)
+static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk, bool wait)
{
u8 modembits[3];
struct gsm_control *ctrl;
@@ -4155,10 +4155,15 @@ static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk)
modembits[2] = (brk << 4) | 2 | EA; /* Length, Break, EA */
len++;
}
- ctrl = gsm_control_send(dlci->gsm, CMD_MSC, modembits, len);
- if (ctrl == NULL)
- return -ENOMEM;
- return gsm_control_wait(dlci->gsm, ctrl);
+ if (wait) {
+ ctrl = gsm_control_send(dlci->gsm, CMD_MSC, modembits, len);
+ if (!ctrl)
+ return -ENOMEM;
+ return gsm_control_wait(dlci->gsm, ctrl);
+ } else {
+ return gsm_control_command(dlci->gsm, CMD_MSC, (const u8 *)&modembits,
+ len);
+ }
}
/**
@@ -4167,7 +4172,7 @@ static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk)
* @brk: break signal
*/
-static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk)
+static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk, bool wait)
{
if (dlci->gsm->dead)
return -EL2HLT;
@@ -4177,7 +4182,7 @@ static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk)
return 0;
} else if (dlci->gsm->encoding == GSM_BASIC_OPT) {
/* Send as MSC control message. */
- return gsm_modem_upd_via_msc(dlci, brk);
+ return gsm_modem_upd_via_msc(dlci, brk, wait);
}
/* Modem status lines are not supported. */
@@ -4243,7 +4248,7 @@ static void gsm_dtr_rts(struct tty_port *port, bool active)
modem_tx &= ~(TIOCM_DTR | TIOCM_RTS);
if (modem_tx != dlci->modem_tx) {
dlci->modem_tx = modem_tx;
- gsm_modem_update(dlci, 0);
+ gsm_modem_update(dlci, 0, true);
}
}
@@ -4449,7 +4454,7 @@ static int gsmtty_tiocmset(struct tty_struct *tty,
if (modem_tx != dlci->modem_tx) {
dlci->modem_tx = modem_tx;
- return gsm_modem_update(dlci, 0);
+ return gsm_modem_update(dlci, 0, true);
}
return 0;
}
@@ -4531,7 +4536,7 @@ static void gsmtty_throttle(struct tty_struct *tty)
dlci->modem_tx &= ~TIOCM_RTS;
dlci->throttled = true;
/* Send an MSC with RTS cleared */
- gsm_modem_update(dlci, 0);
+ gsm_modem_update(dlci, 0, true);
}
static void gsmtty_unthrottle(struct tty_struct *tty)
@@ -4543,7 +4548,7 @@ static void gsmtty_unthrottle(struct tty_struct *tty)
dlci->modem_tx |= TIOCM_RTS;
dlci->throttled = false;
/* Send an MSC with RTS set */
- gsm_modem_update(dlci, 0);
+ gsm_modem_update(dlci, 0, true);
}
static int gsmtty_break_ctl(struct tty_struct *tty, int state)
@@ -4561,7 +4566,7 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state)
if (encode > 0x0F)
encode = 0x0F; /* Best effort */
}
- return gsm_modem_update(dlci, encode);
+ return gsm_modem_update(dlci, encode, true);
}
static void gsmtty_cleanup(struct tty_struct *tty)
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] tty: n_gsm: Don't block input queue by waiting MSC
2025-08-25 13:55 [PATCH] tty: n_gsm: Don't block input queue by waiting MSC Seppo Takalo
@ 2025-08-26 7:08 ` Greg Kroah-Hartman
2025-08-27 12:26 ` [PATCH v2] " Seppo Takalo
0 siblings, 1 reply; 3+ messages in thread
From: Greg Kroah-Hartman @ 2025-08-26 7:08 UTC (permalink / raw)
To: Seppo Takalo; +Cc: linux-serial, linux-kernel
On Mon, Aug 25, 2025 at 04:55:00PM +0300, Seppo Takalo wrote:
> Add parameter "wait" for gsm_modem_update() to indicate if we
> should wait for the response.
>
> Currently gsm_queue() processes incoming frames and when opening
> a DLC channel it calls gsm_dlci_open() which calls gsm_modem_update().
> If basic mode is used it calls gsm_modem_upd_via_msc() and it
> cannot block the input queue by waiting the response to come
> into the same input queue.
>
> Instead allow sending Modem Status Command without waiting for remote
> end to respond.
>
> Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
What commit id does this fix?
> ---
> drivers/tty/n_gsm.c | 33 +++++++++++++++++++--------------
> 1 file changed, 19 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
> index 8dd3f23af3d2..8e8475d9fbeb 100644
> --- a/drivers/tty/n_gsm.c
> +++ b/drivers/tty/n_gsm.c
> @@ -454,7 +454,7 @@ static const u8 gsm_fcs8[256] = {
>
> static void gsm_dlci_close(struct gsm_dlci *dlci);
> static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len);
> -static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk);
> +static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk, bool wait);
Adding a random boolean to a function is almost never a good idea. Now
every time you call this function, you have to go and look up what that
boolean means.
Please never do that, instead make a "wrapper" function that will then
call this "core" function with the boolean set properly. That way you
can name the wrapper functions in a way that describes what it does.
> static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
> u8 ctrl);
> static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg);
> @@ -2174,7 +2174,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
> pr_debug("DLCI %d goes open.\n", dlci->addr);
> /* Send current modem state */
> if (dlci->addr) {
> - gsm_modem_update(dlci, 0);
> + gsm_modem_update(dlci, 0, false);
See, what does false mean? No clue :(
Why not call gsm_modem_update_and_wait() instead?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v2] tty: n_gsm: Don't block input queue by waiting MSC
2025-08-26 7:08 ` Greg Kroah-Hartman
@ 2025-08-27 12:26 ` Seppo Takalo
0 siblings, 0 replies; 3+ messages in thread
From: Seppo Takalo @ 2025-08-27 12:26 UTC (permalink / raw)
To: Greg Kroah-Hartman; +Cc: linux-serial, linux-kernel, Seppo Takalo
Currently gsm_queue() processes incoming frames and when opening
a DLC channel it calls gsm_dlci_open() which calls gsm_modem_update().
If basic mode is used it calls gsm_modem_upd_via_msc() and it
cannot block the input queue by waiting the response to come
into the same input queue.
Instead allow sending Modem Status Command without waiting for remote
end to respond. Define a new function gsm_modem_send_initial_msc()
for this purpose. As MSC is only valid for basic encoding, it does
not do anything for advanced or when convergence layer type 2 is used.
Fixes: 48473802506d ("tty: n_gsm: fix missing update of modem controls after DLCI open")
Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
---
v1 --> v2
- Removed the proposed "bool wait" parameter from gsm_modem_update().
- Defined a new function gsm_modem_send_initial_msc()
drivers/tty/n_gsm.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 8dd3f23af3d2..532027370dff 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -461,6 +461,7 @@ static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg);
static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr);
static void gsmld_write_trigger(struct gsm_mux *gsm);
static void gsmld_write_task(struct work_struct *work);
+static int gsm_modem_send_initial_msc(struct gsm_dlci *dlci);
/**
* gsm_fcs_add - update FCS
@@ -2174,7 +2175,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
pr_debug("DLCI %d goes open.\n", dlci->addr);
/* Send current modem state */
if (dlci->addr) {
- gsm_modem_update(dlci, 0);
+ gsm_modem_send_initial_msc(dlci);
} else {
/* Start keep-alive control */
gsm->ka_num = 0;
@@ -4161,6 +4162,28 @@ static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk)
return gsm_control_wait(dlci->gsm, ctrl);
}
+/**
+ * gsm_modem_send_initial_msc - Send initial modem status message
+ *
+ * @dlci channel
+ *
+ * Send an initial MSC message after DLCI open to set the initial
+ * modem status lines. This is only done for basic mode.
+ * Does not wait for a response as we cannot block the input queue
+ * processing.
+ */
+static int gsm_modem_send_initial_msc(struct gsm_dlci *dlci)
+{
+ u8 modembits[2];
+
+ if (dlci->adaption != 1 || dlci->gsm->encoding != GSM_BASIC_OPT)
+ return 0;
+
+ modembits[0] = (dlci->addr << 2) | 2 | EA; /* DLCI, Valid, EA */
+ modembits[1] = (gsm_encode_modem(dlci) << 1) | EA;
+ return gsm_control_command(dlci->gsm, CMD_MSC, (const u8 *)&modembits, 2);
+}
+
/**
* gsm_modem_update - send modem status line state
* @dlci: channel
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-08-27 12:33 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-25 13:55 [PATCH] tty: n_gsm: Don't block input queue by waiting MSC Seppo Takalo
2025-08-26 7:08 ` Greg Kroah-Hartman
2025-08-27 12:26 ` [PATCH v2] " Seppo Takalo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).