From patchwork Thu Feb 2 14:59:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "D. Starke" X-Patchwork-Id: 51982 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp289918wrn; Thu, 2 Feb 2023 07:05:02 -0800 (PST) X-Google-Smtp-Source: AK7set9gqntmpvvcQuIk/WHWW4XRyBG5EM45575i3XNrmW/Gs57T5g9ua7JcasRVPJ2TjLTr/UNR X-Received: by 2002:a05:6a00:b41:b0:593:fe34:96e5 with SMTP id p1-20020a056a000b4100b00593fe3496e5mr7786903pfo.5.1675350302513; Thu, 02 Feb 2023 07:05:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675350302; cv=none; d=google.com; s=arc-20160816; b=QSYiTqqWDD7sGMHeY3yh3cT0HWqPN9dKPh7iJXWfJ1oy3oAP7ixTAKoXcaBMJtrH3+ dtBMpaEqTqSgGYxQF4p6rxOomsfLv/nMtIcBvqZAbZyHjNN6PyiUdiKo8SuSDNA6rqqN RY4RMim84obvriDCzqGIUT+f8TTtkb18wKQAcuid6QANc0+a9A9+XSK8FCmxN9BW2Fgh l52GMQjDGLkwXjBNoejAZ/xGn3xWi9ZOO8Q09Lk1c5NukhpUeQwX4d8U591369y2mjud KJ9CbWyaosUo9OA8iZcCLt6HAGp3wQWDQigIjDF6Rt+68XGoS7ah7+DGxq4z+304mk3j 2doQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:feedback-id:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dkim-signature; bh=TmNKWQTw0AoAXvhAuQ5lR2bAljisCn7vFHIBxeWBZsk=; b=z7iwiyraQINiNhcWO3wB9oyogKqVqOjIomS7VzSYieD3aEir6lhnnUvuwp6a0NM7Ml VppD5PWd4H3yaNQOjKFkZVA2EqTlY1ktTLD/sVshuOizKdUzI3gZmyHvDTXRYhYJvVuO NdoNcQmjiH4fSGW1jwJ6fG4RTt9r8Dcp3doj3oLXjqOlgzOcRbc22zpgyD5fGhA4fIDH 4gP9duITffMT7Gx32+Nous7m0/aHvXhItUm52K1f+nXc1i13EbfgDJAH/bqm0ewn391q qaNhJQ6H0tfjKm6Ukzd00R2U7XKZitB4TPTDYFUK+0o6Kwn6ArQxDIZ41PcpMKmNZx10 FUcQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@siemens.com header.s=fm1 header.b=IP3xyubL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x75-20020a62864e000000b005941a758cadsi4806364pfd.97.2023.02.02.07.04.47; Thu, 02 Feb 2023 07:05:02 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@siemens.com header.s=fm1 header.b=IP3xyubL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231635AbjBBPA6 (ORCPT + 99 others); Thu, 2 Feb 2023 10:00:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40488 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229935AbjBBPA4 (ORCPT ); Thu, 2 Feb 2023 10:00:56 -0500 Received: from mta-64-227.siemens.flowmailer.net (mta-64-227.siemens.flowmailer.net [185.136.64.227]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3AEA7234D5 for ; Thu, 2 Feb 2023 07:00:52 -0800 (PST) Received: by mta-64-227.siemens.flowmailer.net with ESMTPSA id 20230202150049e6a85b5c5536ee66ec for ; Thu, 02 Feb 2023 16:00:50 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=daniel.starke@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc; bh=TmNKWQTw0AoAXvhAuQ5lR2bAljisCn7vFHIBxeWBZsk=; b=IP3xyubL3mkYcXQKBU4+FIypIv6VNds8tfQJaGltq9hzqOYEstHv8ybTNsTohxDeZU15QC wS2vHMSZyBJFifJbvyak+VtgiaUMq1EgiZKvYCoXzdZ4lXkB+dbSRCO4Imr7LQ9ivCx6m5/k Hi0tNAXeW+UQgyfpfo1tPSzf07Uuk=; From: "D. Starke" To: linux-serial@vger.kernel.org, gregkh@linuxfoundation.org, jirislaby@kernel.org, ilpo.jarvinen@linux.intel.com Cc: linux-kernel@vger.kernel.org, Daniel Starke Subject: [PATCH v2 1/3] tty: n_gsm: add keep alive support Date: Thu, 2 Feb 2023 15:59:32 +0100 Message-Id: <20230202145934.22641-1-daniel.starke@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-314044:519-21489:flowmailer X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756732118511129996?= X-GMAIL-MSGID: =?utf-8?q?1756732118511129996?= From: Daniel Starke n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010. See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516 The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to the newer 27.010 here. Chapters 5.4.6.3.4 and 5.1.8.1.3 describe the test command which can be used to test the mux connection between both sides. Currently, no algorithm is implemented to make use of this command. This requires that each multiplexed upper layer protocol supervises the underlying muxer connection to handle possible connection losses. Introduce an ioctl commands and functions to optionally enable keep alive handling via the test command as described in chapter 5.4.6.3.4. A single incrementing octet is being used to distinguish between multiple retries. Retry count and interval are taken from the general parameters N2 and T2. Note that support for the test command is mandatory and already present in the muxer implementation since the very first version. Also note that the previous ioctl structure gsm_config cannot be extended due to missing checks against zero of the field "unused". Signed-off-by: Daniel Starke --- drivers/tty/n_gsm.c | 106 +++++++++++++++++++++++++++++++++++- include/uapi/linux/gsmmux.h | 17 ++++-- 2 files changed, 117 insertions(+), 6 deletions(-) v1 -> v2: The "unused" fields of "gsm_config" and "gsm_netconfig" have been marked as unusable due to missing checks against zero. See review comments. New ioctl commands GSMIOC_GETCONF_EXT and GSMIOC_SETCONF_EXT together with the structure gsm_config_ext have been added. Reserved fields are included for possible future extensions. Proper check against zero is done. Setting a different value for "keep_alive" via ioctl does not reset the already open DLCI anymore. This is not needed as there is no impact at the peer. gsm_control_keep_alive() has been changed to call spin_unlock_irqrestore() properly in every case. Link: https://lore.kernel.org/all/Y9pfrFPngFVgQUN7@kroah.com/ diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 5783801d6524..d068df1cf2fd 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -318,6 +318,11 @@ struct gsm_mux { struct gsm_control *pending_cmd;/* Our current pending command */ spinlock_t control_lock; /* Protects the pending command */ + /* Keep-alive */ + struct timer_list ka_timer; /* Keep-alive response timer */ + u8 ka_num; /* Keep-alive match pattern */ + int ka_retries; /* Keep-alive retry counter */ + /* Configuration */ int adaption; /* 1 or 2 supported */ u8 ftype; /* UI or UIH */ @@ -325,6 +330,7 @@ struct gsm_mux { unsigned int t3; /* Power wake-up timer in seconds. */ int n2; /* Retry count */ u8 k; /* Window size */ + u32 keep_alive; /* Control channel keep-alive in ms */ /* Statistics (not currently exposed) */ unsigned long bad_fcs; @@ -1897,11 +1903,13 @@ static void gsm_control_response(struct gsm_mux *gsm, unsigned int command, const u8 *data, int clen) { struct gsm_control *ctrl; + struct gsm_dlci *dlci; unsigned long flags; spin_lock_irqsave(&gsm->control_lock, flags); ctrl = gsm->pending_cmd; + dlci = gsm->dlci[0]; command |= 1; /* Does the reply match our command */ if (ctrl != NULL && (command == ctrl->cmd || command == CMD_NSC)) { @@ -1916,6 +1924,54 @@ static void gsm_control_response(struct gsm_mux *gsm, unsigned int command, /* Or did we receive the PN response to our PN command */ } else if (command == CMD_PN) { gsm_control_negotiation(gsm, 0, data, clen); + /* Or did we receive the TEST response to our TEST command */ + } else if (command == CMD_TEST && clen == 1 && *data == gsm->ka_num) { + gsm->ka_retries = -1; /* trigger new keep-alive message */ + if (dlci && !dlci->dead) + mod_timer(&gsm->ka_timer, + jiffies + gsm->keep_alive * HZ / 100); + } + spin_unlock_irqrestore(&gsm->control_lock, flags); +} + +/** + * gsm_control_keep_alive - check timeout or start keep-alive + * @t: timer contained in our gsm object + * + * Called off the keep-alive timer expiry signaling that our link + * partner is not responding anymore. Link will be closed. + * This is also called to startup our timer. + */ + +static void gsm_control_keep_alive(struct timer_list *t) +{ + struct gsm_mux *gsm = from_timer(gsm, t, ka_timer); + unsigned long flags; + + spin_lock_irqsave(&gsm->control_lock, flags); + if (gsm->ka_num && gsm->ka_retries == 0) { + /* Keep-alive expired -> close the link */ + if (debug & DBG_ERRORS) + pr_info("%s keep-alive timed out\n", __func__); + spin_unlock_irqrestore(&gsm->control_lock, flags); + if (gsm->dlci[0]) + gsm_dlci_begin_close(gsm->dlci[0]); + return; + } else if (gsm->keep_alive && gsm->dlci[0] && !gsm->dlci[0]->dead) { + if (gsm->ka_retries > 0) { + /* T2 expired for keep-alive -> resend */ + gsm->ka_retries--; + } else { + /* Start keep-alive timer */ + gsm->ka_num++; + if (!gsm->ka_num) + gsm->ka_num++; + gsm->ka_retries = gsm->n2; + } + gsm_control_command(gsm, CMD_TEST, &gsm->ka_num, + sizeof(gsm->ka_num)); + mod_timer(&gsm->ka_timer, + jiffies + gsm->t2 * HZ / 100); } spin_unlock_irqrestore(&gsm->control_lock, flags); } @@ -2061,8 +2117,10 @@ static void gsm_dlci_close(struct gsm_dlci *dlci) /* Ensure that gsmtty_open() can return. */ tty_port_set_initialized(&dlci->port, false); wake_up_interruptible(&dlci->port.open_wait); - } else + } else { + del_timer(&dlci->gsm->ka_timer); dlci->gsm->dead = true; + } /* A DLCI 0 close is a MUX termination so we need to kick that back to userspace somehow */ gsm_dlci_data_kick(dlci); @@ -2078,6 +2136,8 @@ static void gsm_dlci_close(struct gsm_dlci *dlci) static void gsm_dlci_open(struct gsm_dlci *dlci) { + struct gsm_mux *gsm = dlci->gsm; + /* Note that SABM UA .. SABM UA first UA lost can mean that we go open -> open */ del_timer(&dlci->t1); @@ -2087,8 +2147,15 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) if (debug & DBG_ERRORS) pr_debug("DLCI %d goes open.\n", dlci->addr); /* Send current modem state */ - if (dlci->addr) + if (dlci->addr) { gsm_modem_update(dlci, 0); + } else { + /* Start keep-alive control */ + gsm->ka_num = 0; + gsm->ka_retries = -1; + mod_timer(&gsm->ka_timer, + jiffies + gsm->keep_alive * HZ / 100); + } gsm_dlci_data_kick(dlci); wake_up(&dlci->gsm->event); } @@ -2840,6 +2907,7 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) /* Finish outstanding timers, making sure they are done */ del_timer_sync(&gsm->kick_timer); del_timer_sync(&gsm->t2_timer); + del_timer_sync(&gsm->ka_timer); /* Finish writing to ldisc */ flush_work(&gsm->tx_work); @@ -2987,6 +3055,7 @@ static struct gsm_mux *gsm_alloc_mux(void) INIT_LIST_HEAD(&gsm->tx_data_list); timer_setup(&gsm->kick_timer, gsm_kick_timer, 0); timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); + timer_setup(&gsm->ka_timer, gsm_control_keep_alive, 0); INIT_WORK(&gsm->tx_work, gsmld_write_task); init_waitqueue_head(&gsm->event); spin_lock_init(&gsm->control_lock); @@ -3003,6 +3072,7 @@ static struct gsm_mux *gsm_alloc_mux(void) gsm->mru = 64; /* Default to encoding 1 so these should be 64 */ gsm->mtu = 64; gsm->dead = true; /* Avoid early tty opens */ + gsm->keep_alive = 0; /* Disabled */ /* Store the instance to the mux array or abort if no space is * available. @@ -3138,6 +3208,28 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) return 0; } +static void gsm_copy_config_ext_values(struct gsm_mux *gsm, + struct gsm_config_ext *ce) +{ + memset(ce, 0, sizeof(*ce)); + ce->keep_alive = gsm->keep_alive; +} + +static int gsm_config_ext(struct gsm_mux *gsm, struct gsm_config_ext *ce) +{ + unsigned int i; + + gsm->keep_alive = ce->keep_alive; + /* + * Check that userspace doesn't put stuff in here to prevent breakages + * in the future. + */ + for (i = 0; i < ARRAY_SIZE(ce->reserved); i++) + if (ce->reserved[i]) + return -EINVAL; + return 0; +} + /** * gsmld_output - write to link * @gsm: our mux @@ -3456,6 +3548,7 @@ static int gsmld_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct gsm_config c; + struct gsm_config_ext ce; struct gsm_mux *gsm = tty->disc_data; unsigned int base; @@ -3472,6 +3565,15 @@ static int gsmld_ioctl(struct tty_struct *tty, unsigned int cmd, case GSMIOC_GETFIRST: base = mux_num_to_base(gsm); return put_user(base + 1, (__u32 __user *)arg); + case GSMIOC_GETCONF_EXT: + gsm_copy_config_ext_values(gsm, &ce); + if (copy_to_user((void __user *)arg, &ce, sizeof(ce))) + return -EFAULT; + return 0; + case GSMIOC_SETCONF_EXT: + if (copy_from_user(&ce, (void __user *)arg, sizeof(ce))) + return -EFAULT; + return gsm_config_ext(gsm, &ce); default: return n_tty_ioctl_helper(tty, cmd, arg); } diff --git a/include/uapi/linux/gsmmux.h b/include/uapi/linux/gsmmux.h index cb8693b39cb7..98de2570d79b 100644 --- a/include/uapi/linux/gsmmux.h +++ b/include/uapi/linux/gsmmux.h @@ -19,8 +19,7 @@ struct gsm_config unsigned int mtu; unsigned int k; unsigned int i; - unsigned int unused[8]; /* Padding for expansion without - breaking stuff */ + unsigned int unused[8]; /* Can not be used */ }; #define GSMIOC_GETCONF _IOR('G', 0, struct gsm_config) @@ -29,9 +28,9 @@ struct gsm_config struct gsm_netconfig { unsigned int adaption; /* Adaption to use in network mode */ unsigned short protocol;/* Protocol to use - only ETH_P_IP supported */ - unsigned short unused2; + unsigned short unused2; /* Can not be used */ char if_name[IFNAMSIZ]; /* interface name format string */ - __u8 unused[28]; /* For future use */ + __u8 unused[28]; /* Can not be used */ }; #define GSMIOC_ENABLE_NET _IOW('G', 2, struct gsm_netconfig) @@ -40,4 +39,14 @@ struct gsm_netconfig { /* get the base tty number for a configured gsmmux tty */ #define GSMIOC_GETFIRST _IOR('G', 4, __u32) +struct gsm_config_ext { + __u32 keep_alive; /* Control channel keep-alive in 1/100th of a + * second (0 to disable) + */ + __u32 reserved[7]; /* For future use */ +}; + +#define GSMIOC_GETCONF_EXT _IOR('G', 5, struct gsm_config_ext) +#define GSMIOC_SETCONF_EXT _IOW('G', 6, struct gsm_config_ext) + #endif From patchwork Thu Feb 2 14:59:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "D. Starke" X-Patchwork-Id: 51983 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp290097wrn; Thu, 2 Feb 2023 07:05:16 -0800 (PST) X-Google-Smtp-Source: AK7set8fY49YhDvteShq1od3NgochyjFnLZxf90ufCatI4qRbVMBH6r6o+2hVwMgQO52vo7YX5ZT X-Received: by 2002:a17:906:c5a:b0:88e:e926:8bb1 with SMTP id t26-20020a1709060c5a00b0088ee9268bb1mr1703540ejf.76.1675350316333; Thu, 02 Feb 2023 07:05:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675350316; cv=none; d=google.com; s=arc-20160816; b=VExy8MnZELafpZJobqcHNBz//1qdzv3rrvTRpE+rfQIirf8ylJZtMpszgk84cC1Y/o Hn6FgVydAKJeq2LPtRftjXgiWevXp3ykXATi/Tmix2fyCl/9Rn8wmqu9ZtlRdtgdKoSv jb1rSWaMzSYOoKBYesvODqfRSTJuW91/ZaPWjan1A65+3NUmwr67APXiM396PFJEaFNu gm4HFKVI254o8a9MAWmgjw3ZePbe+9odmOxaPigBdySxedwoCPgTlfReyQhfjy5Vjijf HIOzUuQ9pvO6NMG4kCSvVAe0NcjAGpNyQGkUUioOGFKgTe8XQjJ9m/5kTrKtzGacNYb8 x0NQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:feedback-id:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=CGxEhyAoxwEddJ0xl4OF2ojfXEmQZFbiyIt4XcYZYMI=; b=mlAtiFL9DY7hPgLoLq7qCOk8gcCK5DZF3+ZggKt4ejF+SynJXuNJP2JejZKANbf5Qy 2Y9lMoRzGA5wjgDvmFIsTwxZMg86P1FpC53q9DyjMbarz0o7DULS0z8CAWMh58FEQjal 0PRx0VjbG1RZzDymbvu49BFurAKj1BrNM0TX+/QYSmsFvtrLrzU5bTaSrkLCsSkUYBRy 4LX7XSzrCycbeHzUBd/xAYzGZUKyU6BBBjjhAPxAo6HrQScxzWvSERS6H+DRge5Ngaz1 BPUfxLkd33g+MMPdMzCqbRrMU1vsbrQg0ia+iUaDVoqzthQ3+DKUjIcEFKGjjZzjCXs+ pQpA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@siemens.com header.s=fm1 header.b=oFm7tsEb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ew24-20020a170907951800b0088c377392acsi9305324ejc.466.2023.02.02.07.04.51; Thu, 02 Feb 2023 07:05:16 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@siemens.com header.s=fm1 header.b=oFm7tsEb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231835AbjBBPBB (ORCPT + 99 others); Thu, 2 Feb 2023 10:01:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40500 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229479AbjBBPA4 (ORCPT ); Thu, 2 Feb 2023 10:00:56 -0500 Received: from mta-65-225.siemens.flowmailer.net (mta-65-225.siemens.flowmailer.net [185.136.65.225]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9CAF61E28E for ; Thu, 2 Feb 2023 07:00:54 -0800 (PST) Received: by mta-65-225.siemens.flowmailer.net with ESMTPSA id 20230202150051f2b4f0df1809a26236 for ; Thu, 02 Feb 2023 16:00:52 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=daniel.starke@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=CGxEhyAoxwEddJ0xl4OF2ojfXEmQZFbiyIt4XcYZYMI=; b=oFm7tsEbzNjln8ACwbYSnM8fp5u8CRuWKKLUxzh4QBJSiSe2NXcTPMrOAYNrMOFzYSSOXe sUVP86thOq5sefEzlqiL2VWEeT2g6n9SZXzRotnTvT5jn43+U3w7lzz0bJf9HwLO/k8Kj6pG /quUsM1DNz0abYmXxhdJlbTsB3LBU=; From: "D. Starke" To: linux-serial@vger.kernel.org, gregkh@linuxfoundation.org, jirislaby@kernel.org, ilpo.jarvinen@linux.intel.com Cc: linux-kernel@vger.kernel.org, Daniel Starke Subject: [PATCH v2 2/3] tty: n_gsm: add RING/CD control support Date: Thu, 2 Feb 2023 15:59:33 +0100 Message-Id: <20230202145934.22641-2-daniel.starke@siemens.com> In-Reply-To: <20230202145934.22641-1-daniel.starke@siemens.com> References: <20230202145934.22641-1-daniel.starke@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-314044:519-21489:flowmailer X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756732133350836148?= X-GMAIL-MSGID: =?utf-8?q?1756732133350836148?= From: Daniel Starke The status lines ring and carrier detect are used by the modem to signal incoming calls (RING) or an established connection (CD). This is implemented as physical lines on a standard RS232 connection. However, the muxer protocol encodes these status lines as modem bits IC and DV. These incoming lines are masked by tty driver (see tty_io.c) and cannot be set by a user application. Allow setting RING via TIOCM_OUT1 and CD via TIOCM_OUT2 to allow implementation of a modem or modem emulator. Signed-off-by: Daniel Starke --- drivers/tty/n_gsm.c | 5 +++++ 1 file changed, 5 insertions(+) v1 -> v2: No changes. diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index d068df1cf2fd..cf1ab7d619d9 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -546,6 +546,11 @@ static u8 gsm_encode_modem(const struct gsm_dlci *dlci) modembits |= MDM_IC; if (dlci->modem_tx & TIOCM_CD || dlci->gsm->initiator) modembits |= MDM_DV; + /* special mappings for passive side to operate as UE */ + if (dlci->modem_tx & TIOCM_OUT1) + modembits |= MDM_IC; + if (dlci->modem_tx & TIOCM_OUT2) + modembits |= MDM_DV; return modembits; } From patchwork Thu Feb 2 14:59:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "D. Starke" X-Patchwork-Id: 51984 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp290297wrn; Thu, 2 Feb 2023 07:05:30 -0800 (PST) X-Google-Smtp-Source: AK7set8vxXT70lmy7JxunkoCPVruGV+VI7yIKeuXKCbohdHyNaBkekxRTsFUsJFY0I7M1g+gN6yS X-Received: by 2002:a05:6a20:a001:b0:b8:c5b3:bfc with SMTP id p1-20020a056a20a00100b000b8c5b30bfcmr7468762pzj.39.1675350330611; Thu, 02 Feb 2023 07:05:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675350330; cv=none; d=google.com; s=arc-20160816; b=exFwqvS6SwYdIwxoWmohHnKnvQiJyB6KK7qb6EwERCuABMEgJuZr39V/lNAT2Mv1jT qmtPOonlkB+VaEelRQh56EvvdFueSBH8ZqcNZT0MMZCfj9A5wYiqFY6RmxzuE4B0F1i9 3avOO/stu9C3Qg4Ff5wf98GTHslC08cn/gv7h0q8gocKb6U9J2XrNMKyTUw3hklQTeov yJ8GRG7qEEVt/RL4mBDvSHCN2nsl455szcNI33nd1BTrPUnHs6RGOh8tNkhf6CetL8JV CKoRcVScFH375azpZHJFkN5i3mY/0NwTArmm8HG1XePQaZtKKodQy/twSkxFii9/PaiK R9iw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:feedback-id:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=YdcoFftLnFR/AK9G1BlGcWmP90uXq6edhg1S5lsCyRU=; b=n/L//50MS3sM6ekYBAqiPUfPSkPPtMO6XBUR+Lp3FmbKfiwVJvNUVZr3NFvfXMzVj6 kcP603CZ80cRQ0M3NCayPt+7+6nXdWg/PTgoVLfJEfPVQcXfv/eZLvLUXmxtO8IUDmy2 z7c2I3xs6Q5UAk+vc271VoL+yrSr+BVxNTsxvY0qmGJrG9spTUXXzqcq4QSIziruWB76 c11cuJFHpCbhh2ftg26LhLFu4zOdeS2OS+mschEHVg8MmYLcg/Th7rIuxvuMOLnXTwDB O7Ua/iefX5Q1RH2UhFZK9rLyMzreNSGlLnhV7YigL0lMTnPkyY1DiGaDlRs9Pp8TTW/O 5RZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@siemens.com header.s=fm1 header.b=MD6mRlsf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p29-20020a63741d000000b004ae2bd6b8casi22422879pgc.808.2023.02.02.07.05.08; Thu, 02 Feb 2023 07:05:30 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@siemens.com header.s=fm1 header.b=MD6mRlsf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232007AbjBBPCQ (ORCPT + 99 others); Thu, 2 Feb 2023 10:02:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232088AbjBBPCL (ORCPT ); Thu, 2 Feb 2023 10:02:11 -0500 X-Greylist: delayed 62 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Thu, 02 Feb 2023 07:01:59 PST Received: from mta-64-225.siemens.flowmailer.net (mta-64-225.siemens.flowmailer.net [185.136.64.225]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 39220222D4 for ; Thu, 2 Feb 2023 07:01:57 -0800 (PST) Received: by mta-64-225.siemens.flowmailer.net with ESMTPSA id 20230202150052df0c5fd652493057c5 for ; Thu, 02 Feb 2023 16:00:53 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=daniel.starke@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=YdcoFftLnFR/AK9G1BlGcWmP90uXq6edhg1S5lsCyRU=; b=MD6mRlsfiPecqm31pMlgpw6gJKBqmkfeIeoKLZUgIDHWTJrsd5fABfT62ZY/IgJysdDBw3 2DxsnoEXD41hpz5D36YnHIOJ2o8sEi6WcWdrRs8IuKjP1VeaaoBAXVwQYrq4UfOhj64/+3R1 GOHE6T5TFODzYf7MpD2NkhkMd9ANI=; From: "D. Starke" To: linux-serial@vger.kernel.org, gregkh@linuxfoundation.org, jirislaby@kernel.org, ilpo.jarvinen@linux.intel.com Cc: linux-kernel@vger.kernel.org, Daniel Starke Subject: [PATCH v2 3/3] tty: n_gsm: add TIOCMIWAIT support Date: Thu, 2 Feb 2023 15:59:34 +0100 Message-Id: <20230202145934.22641-3-daniel.starke@siemens.com> In-Reply-To: <20230202145934.22641-1-daniel.starke@siemens.com> References: <20230202145934.22641-1-daniel.starke@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-314044:519-21489:flowmailer X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756732148090794395?= X-GMAIL-MSGID: =?utf-8?q?1756732148090794395?= From: Daniel Starke Add support for the TIOCMIWAIT ioctl on the virtual ttys. This enables the user to wait for virtual modem signals like RING. More work is needed to support also TIOCGICOUNT. Signed-off-by: Daniel Starke --- drivers/tty/n_gsm.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) v1 -> v2: A remark regarding TIOCGICOUNT has been added to the commit message. Wake ups in gsm_dlci_close() and gsm_dlci_begin_close() have been added to cope with closed DLCI during TIOCMIWAIT. gsm_wait_modem_change() has been properly commented to highlight all use cases. Furthermore, the function has been simplified and a DLCI state condition added to the wait_event_interruptible() call to deal with DLCI termination during TIOCMIWAIT correctly. Link: https://lore.kernel.org/all/Y9pgT4VcW3oGaSbY@kroah.com/ diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index cf1ab7d619d9..4f710a6309a7 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1542,6 +1542,7 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, if (brk & 0x01) tty_insert_flip_char(&dlci->port, 0, TTY_BREAK); dlci->modem_rx = mlines; + wake_up_interruptible(&dlci->gsm->event); } /** @@ -2129,7 +2130,7 @@ static void gsm_dlci_close(struct gsm_dlci *dlci) /* A DLCI 0 close is a MUX termination so we need to kick that back to userspace somehow */ gsm_dlci_data_kick(dlci); - wake_up(&dlci->gsm->event); + wake_up_all(&dlci->gsm->event); } /** @@ -2339,6 +2340,7 @@ static void gsm_dlci_begin_close(struct gsm_dlci *dlci) dlci->state = DLCI_CLOSING; gsm_command(dlci->gsm, dlci->addr, DISC|PF); mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); + wake_up_interruptible(&gsm->event); } /** @@ -3877,6 +3879,33 @@ static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk) return -EPROTONOSUPPORT; } +/** + * gsm_wait_modem_change - wait for modem status line change + * @dlci: channel + * @mask: modem status line bits + * + * The function returns if: + * - any given modem status line bit changed + * - the wait event function got interrupted (e.g. by a signal) + * - the underlying DLCI was closed + * - the underlying ldisc device was removed + */ +static int gsm_wait_modem_change(struct gsm_dlci *dlci, u32 mask) +{ + struct gsm_mux *gsm = dlci->gsm; + u32 old = dlci->modem_rx; + int ret; + + ret = wait_event_interruptible(gsm->event, gsm->dead || + dlci->state != DLCI_OPEN || + (old ^ dlci->modem_rx) & mask); + if (gsm->dead) + return -ENODEV; + if (dlci->state != DLCI_OPEN) + return -EL2NSYNC; + return ret; +} + static bool gsm_carrier_raised(struct tty_port *port) { struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port); @@ -4136,6 +4165,8 @@ static int gsmtty_ioctl(struct tty_struct *tty, gsm_destroy_network(dlci); mutex_unlock(&dlci->mutex); return 0; + case TIOCMIWAIT: + return gsm_wait_modem_change(dlci, arg); default: return -ENOIOCTLCMD; }