Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp800196pxb; Fri, 22 Apr 2022 11:24:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxxiLh81seztFKCElir+ZUU+hmFVDF1CAvbEuJWZ1heRvupozuIkwBQrlGowHSCBxjQhlh7 X-Received: by 2002:a63:185f:0:b0:386:1838:8d0 with SMTP id 31-20020a63185f000000b00386183808d0mr4997791pgy.161.1650651862430; Fri, 22 Apr 2022 11:24:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1650651862; cv=none; d=google.com; s=arc-20160816; b=haY3ofxXGXSmg3ozXh9bNHQukg0cRNo0n7Y5ZpNnTQvQljBREllx3gkSjhquXOrQO8 yTww3icSEbRP1sk/B7Z8wGUJrVSciS4el61e6W+/nwg6Dc4avl7GN7tsB5JPyEBdsGK+ otdJ5G1MACRY9EoIrCBLoDA+z4ycWQrX9t5QJykSYlb3ia/QTJINOGApEhZoN0Vf759b NU2hWR6NHzdGT6We5qQRuzKvxjstLos3tXGd21Fc+XZi9oWqX5Xyt/WWRu3/0qyqZfIM aQQAc6BnpCdZIODXS5vxHRZni8OdmKMge+WFIn+f+Vf2wDb6rzndHwjux9BF/hLHhBkT OvJQ== 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=N+qgC+uSMHsyklwVh7o4vM2DFt2Is5fDal+efTqi/0g=; b=M/9nnQBcHqc2uhFCGJiiZ2zb3f4/NZB0mQy3ms04/zNEkt4vViyWzjah/o35bkanNz UlhK7Y+eEmyMh3ONgLQsiEU//LiYlM1Asl148ckj3j/0llTfsFSnPXZA1WUc0c1uWkB8 fznu4HxHfu0+IKIEfzVBtCKS8L6jZr6FMg47SrsIZkgMi0HRAKCuFHoKhgzS8uRN1lE1 XHQRUuzzoM/hcq68mqOqFm6ya5lBydWI13fyhqnErF36GrzH580DpUuD5ZEuG/gSsfEz ML1co4Q+6W07JzmwvmwdXBIhHod5ylggZtKm5QtGjG0nuaDMv1gx3kAPg2mNKk8fG3+W jhjQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@siemens.com header.s=fm1 header.b="JWv/SILh"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id e17-20020a635451000000b0038233be8161si8241354pgm.645.2022.04.22.11.24.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Apr 2022 11:24:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@siemens.com header.s=fm1 header.b="JWv/SILh"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 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 [IPv6:2620:137:e000::1:20]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id C8919146EC9; Fri, 22 Apr 2022 10:54:02 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1444701AbiDVHOm (ORCPT + 99 others); Fri, 22 Apr 2022 03:14:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1444598AbiDVHOg (ORCPT ); Fri, 22 Apr 2022 03:14:36 -0400 X-Greylist: delayed 64 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Fri, 22 Apr 2022 00:11:43 PDT 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 E843C50E34 for ; Fri, 22 Apr 2022 00:11:41 -0700 (PDT) Received: by mta-64-225.siemens.flowmailer.net with ESMTPSA id 20220422071036d95c0d008e8d39ccc9 for ; Fri, 22 Apr 2022 09:10:36 +0200 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=N+qgC+uSMHsyklwVh7o4vM2DFt2Is5fDal+efTqi/0g=; b=JWv/SILhzSdJ3lIzagC04ZWXR5Hmsq0RH+2Ge1LJL9QKBLmRXqx3+qi/NvyrU8O50bH+mZ IUbKXhWkJ5dhs1UElflSYEAZsKF/Jwzw3qLH4+32QNCi9j7UISu1GMAPDM8TT3wF1FnttvBd gnEmZLiplUs0xBWHZ2zAvKKIujviI=; From: "D. Starke" To: linux-serial@vger.kernel.org, gregkh@linuxfoundation.org, jirislaby@kernel.org Cc: linux-kernel@vger.kernel.org, Daniel Starke Subject: [PATCH 1/3] tty: n_gsm: fix broken virtual tty handling Date: Fri, 22 Apr 2022 00:10:23 -0700 Message-Id: <20220422071025.5490-1-daniel.starke@siemens.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-314044:519-21489:flowmailer X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE autolearn=no 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 From: Daniel Starke Dynamic virtual tty registration was introduced to allow the user to handle these cases with uevent rules. The following commits relate to this: Commit 5b87686e3203 ("tty: n_gsm: Modify gsmtty driver register method when config requester") Commit 0b91b5332368 ("tty: n_gsm: Save dlci address open status when config requester") Commit 46292622ad73 ("tty: n_gsm: clean up indenting in gsm_queue()") However, the following behavior can be seen with this implementation: - n_gsm ldisc is activated via ioctl - all configuration parameters are set to their default value (initiator=0) - the mux gets activated and attached and gsmtty0 is being registered in in gsm_dlci_open() after DLCI 0 was established (DLCI 0 is the control channel) - the user configures n_gsm via ioctl GSMIOC_SETCONF as initiator - this re-attaches the n_gsm mux - no new gsmtty devices are registered in gsmld_attach_gsm() because the mux is already active - the initiator side registered only the control channel as gsmtty0 (which should never happen) and no user channel tty The commits above make it impossible to operate the initiator side as no user channel tty is or will be available. On the other hand, this behavior will make it also impossible to allow DLCI parameter negotiation on responder side in the future. The responder side first needs to provide a device for the application before the application can set its parameters of the associated DLCI via ioctl. Note that the user application is still able to detect a link establishment without relaying to uevent by waiting for DTR open on responder side. This is the same behavior as on a physical serial interface. And on initiator side a tty hangup can be detected if a link establishment request failed. Revert the commits above completely to always register all user channels and no control channel after mux attachment. No other changes are made. Fixes: 5b87686e3203 ("tty: n_gsm: Modify gsmtty driver register method when config requester") Cc: stable@vger.kernel.org Signed-off-by: Daniel Starke --- drivers/tty/n_gsm.c | 87 ++++++++------------------------------------- 1 file changed, 15 insertions(+), 72 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 979dc9151383..99fe54247a87 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -272,10 +272,6 @@ static DEFINE_SPINLOCK(gsm_mux_lock); static struct tty_driver *gsm_tty_driver; -/* Save dlci open address */ -static int addr_open[256] = { 0 }; -/* Save dlci open count */ -static int addr_cnt; /* * This section of the driver logic implements the GSM encodings * both the basic and the 'advanced'. Reliable transport is not @@ -1185,7 +1181,6 @@ static void gsm_control_rls(struct gsm_mux *gsm, const u8 *data, int clen) } static void gsm_dlci_begin_close(struct gsm_dlci *dlci); -static void gsm_dlci_close(struct gsm_dlci *dlci); /** * gsm_control_message - DLCI 0 control processing @@ -1204,28 +1199,15 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, { u8 buf[1]; unsigned long flags; - struct gsm_dlci *dlci; - int i; - int address; switch (command) { case CMD_CLD: { - if (addr_cnt > 0) { - for (i = 0; i < addr_cnt; i++) { - address = addr_open[i]; - dlci = gsm->dlci[address]; - gsm_dlci_close(dlci); - addr_open[i] = 0; - } - } + struct gsm_dlci *dlci = gsm->dlci[0]; /* Modem wishes to close down */ - dlci = gsm->dlci[0]; if (dlci) { dlci->dead = true; gsm->dead = true; - gsm_dlci_close(dlci); - addr_cnt = 0; - gsm_response(gsm, 0, UA|PF); + gsm_dlci_begin_close(dlci); } } break; @@ -1459,8 +1441,6 @@ static void gsm_dlci_close(struct gsm_dlci *dlci) wake_up_interruptible(&dlci->port.open_wait); } else dlci->gsm->dead = true; - /* Unregister gsmtty driver,report gsmtty dev remove uevent for user */ - tty_unregister_device(gsm_tty_driver, dlci->addr); wake_up(&dlci->gsm->event); /* A DLCI 0 close is a MUX termination so we need to kick that back to userspace somehow */ @@ -1482,8 +1462,6 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) dlci->state = DLCI_OPEN; if (debug & 8) pr_debug("DLCI %d goes open.\n", dlci->addr); - /* Register gsmtty driver,report gsmtty dev add uevent for user */ - tty_register_device(gsm_tty_driver, dlci->addr, NULL); /* Send current modem state */ if (dlci->addr) gsmtty_modem_update(dlci, 0); @@ -1794,7 +1772,6 @@ static void gsm_queue(struct gsm_mux *gsm) struct gsm_dlci *dlci; u8 cr; int address; - int i, j, k, address_tmp; if (gsm->fcs != GOOD_FCS) { gsm->bad_fcs++; @@ -1826,11 +1803,6 @@ static void gsm_queue(struct gsm_mux *gsm) else { gsm_response(gsm, address, UA|PF); gsm_dlci_open(dlci); - /* Save dlci open address */ - if (address) { - addr_open[addr_cnt] = address; - addr_cnt++; - } } break; case DISC|PF: @@ -1841,33 +1813,8 @@ static void gsm_queue(struct gsm_mux *gsm) return; } /* Real close complete */ - if (!address) { - if (addr_cnt > 0) { - for (i = 0; i < addr_cnt; i++) { - address = addr_open[i]; - dlci = gsm->dlci[address]; - gsm_dlci_close(dlci); - addr_open[i] = 0; - } - } - dlci = gsm->dlci[0]; - gsm_dlci_close(dlci); - addr_cnt = 0; - gsm_response(gsm, 0, UA|PF); - } else { - gsm_response(gsm, address, UA|PF); - gsm_dlci_close(dlci); - /* clear dlci address */ - for (j = 0; j < addr_cnt; j++) { - address_tmp = addr_open[j]; - if (address_tmp == address) { - for (k = j; k < addr_cnt; k++) - addr_open[k] = addr_open[k+1]; - addr_cnt--; - break; - } - } - } + gsm_response(gsm, address, UA|PF); + gsm_dlci_close(dlci); break; case UA|PF: if (cr == 0 || dlci == NULL) @@ -2451,19 +2398,17 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) else { /* Don't register device 0 - this is the control channel and not a usable tty interface */ - if (gsm->initiator) { - base = mux_num_to_base(gsm); /* Base for this MUX */ - for (i = 1; i < NUM_DLCI; i++) { - struct device *dev; + base = mux_num_to_base(gsm); /* Base for this MUX */ + for (i = 1; i < NUM_DLCI; i++) { + struct device *dev; - dev = tty_register_device(gsm_tty_driver, + dev = tty_register_device(gsm_tty_driver, base + i, NULL); - if (IS_ERR(dev)) { - for (i--; i >= 1; i--) - tty_unregister_device(gsm_tty_driver, - base + i); - return PTR_ERR(dev); - } + if (IS_ERR(dev)) { + for (i--; i >= 1; i--) + tty_unregister_device(gsm_tty_driver, + base + i); + return PTR_ERR(dev); } } } @@ -2485,10 +2430,8 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) int i; WARN_ON(tty != gsm->tty); - if (gsm->initiator) { - for (i = 1; i < NUM_DLCI; i++) - tty_unregister_device(gsm_tty_driver, base + i); - } + for (i = 1; i < NUM_DLCI; i++) + tty_unregister_device(gsm_tty_driver, base + i); tty_kref_put(gsm->tty); gsm->tty = NULL; } -- 2.25.1