Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp3777916pxj; Mon, 7 Jun 2021 21:05:42 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz4fYq31UNmPQTyWfgZCjNPk44Z350oaVYX4w4s1HpGV5Oja/gxgf4CFohmFYM8L8SH0Xtn X-Received: by 2002:a17:906:b352:: with SMTP id cd18mr20621793ejb.222.1623125142802; Mon, 07 Jun 2021 21:05:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623125142; cv=none; d=google.com; s=arc-20160816; b=NixSx1+QC1oi+KSl1DobaeAkdBQHQf0QClR/H7mHHEY3rCCxY+QzwcBslqIiVjPhXm RBZEf9fHDFUkeJlpqwVX8PXhFeADvnWoACpJNTCzBIibc92oNI1ivIeZzDXic61Ms7nD HmHTODoevUFaNhQPUrEfvC2GPcVCDM2aipREIg4Thx+rxtWgBoK4/fzb93pZAmrBpZdx zYVqyeHktJ9bk7zZ/InBV9yzjcLnmtP60oG6/ja7HRRu2LB5F+izVqn61qkNuKd6vHzw SRY9CASaijpwssvyK2TQigOb6OuhRL73zBwPe/4wTTRmM1EkDIMCNtp7P85ju1tl+7pf Py2A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=eweejLmoSrLMGgxviVt5Oq8o8u/eXalaOHg4faHNMwQ=; b=idpTQwB/PQdTnTAf8BkREwSQIXs8NpP/r9O8xEPtsG90XuSZyEWr2Sn805IMwBlCRd sw6RaKcFJs2N2XBwPy9tcY/wJrtIRf+owjHvfF32Id21a6KrimF4MYHHJfWXIiQa2uNc q1tWPNApYJP19xPd7zTLZhczokVo4tc9zCbdA6xdlmH/6HTwCFpYeUxcfnI/rypbx5KV vKRLa7N6fwidNYHauVBPciHmT6ynY6sLnkXaiztmGTEsBZZznV1Yj61Yp/1XsQXq9PRc H3EVk5E5HfAsCRL1JIwjcNi4lBptA9vbJ5TE0mrfhFmd3Gp7bpHkvNSS27NwdAoBrJf4 EJHw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=DEicVTJl; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id dd18si13366211edb.445.2021.06.07.21.05.19; Mon, 07 Jun 2021 21:05:42 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=DEicVTJl; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231217AbhFHEGA (ORCPT + 99 others); Tue, 8 Jun 2021 00:06:00 -0400 Received: from mail-lf1-f44.google.com ([209.85.167.44]:42556 "EHLO mail-lf1-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230522AbhFHEF7 (ORCPT ); Tue, 8 Jun 2021 00:05:59 -0400 Received: by mail-lf1-f44.google.com with SMTP id j2so2243755lfg.9; Mon, 07 Jun 2021 21:03:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eweejLmoSrLMGgxviVt5Oq8o8u/eXalaOHg4faHNMwQ=; b=DEicVTJlL9BJlXrfsbLc8FfsrzgKQgxkUoQ5o1rbmVI3H5agGQujSv0jcl7ut64fJd cv367FiRFk0s39P05eIUsVZTue7u0k9cmoLtsmVqp3zUq0Gi7+PaH9OSNOM1jy3WEVah OgVySP537dX9jqq7DzBQWM6J/uaiKaHk0Qb9KBIWkxReQsLLVBhIOUOdQS/38BWPgXAS D9by5jIy6im5w6CeaxjnQQ4EDteImBKa5Ec+l6nFQRP4FAlE4R+P76kcsFFdww7eSaEy rG6GaS2Zt8Mctcp9AQox91F+Gx5Sf/DxgkJKy+TLBW8Ywu9pIbitj+PcuGodxR71CrZ/ pfiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eweejLmoSrLMGgxviVt5Oq8o8u/eXalaOHg4faHNMwQ=; b=TSvw63mmogpV6Z2vUXQYLuG7gY71dlYwds3lZH46TsTRkzAokSyMSG/Qs6ib+0+Jv5 wn1JPoR/RMhWqCECCQmDznjPWzUxb2WWT6JhCymBj7iHgbNfggDHNiEtCz6Ibhhsqm9J QezDUiiHtSr++sdNtt+epGVzBNj3DQkIKECFNhz/gPr3EmSdzpqDUlErAXybfQHk5J3t 99wRhBLIomDYN8fuGfWIBCen1CclrKiZs0aq0um/LWEoRBhkvdy+3UdE/JxXMLBR3XgE PdfwPYFJHNPLJN+QWQ9mmBWKFHbpLIbGH38WXwQZjh7apAH21KzuIRxPLcE2ZGSHjEmu ImbQ== X-Gm-Message-State: AOAM530bpuZWJMbLC9vK8/5pmKuMGU5Pfe0RDRdrVEN8S03vssZxJiBu HvR98umXrSIHhwmXBbZ0MSY= X-Received: by 2002:a19:ec14:: with SMTP id b20mr14595414lfa.244.1623124977790; Mon, 07 Jun 2021 21:02:57 -0700 (PDT) Received: from rsa-laptop.internal.lan ([217.25.229.52]) by smtp.gmail.com with ESMTPSA id l23sm1729096lfj.26.2021.06.07.21.02.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Jun 2021 21:02:57 -0700 (PDT) From: Sergey Ryazanov To: Loic Poulain , "David S. Miller" , Jakub Kicinski Cc: netdev@vger.kernel.org, linux-wireless@vger.kernel.org Subject: [PATCH 09/10] net: wwan: core: implement terminal ioctls for AT port Date: Tue, 8 Jun 2021 07:02:40 +0300 Message-Id: <20210608040241.10658-10-ryazanov.s.a@gmail.com> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210608040241.10658-1-ryazanov.s.a@gmail.com> References: <20210608040241.10658-1-ryazanov.s.a@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org It is not unreasonable to assume that users will use terminal emulation software to communicate directly with a WWAN device over the AT port. But terminal emulators will refuse to work with a device that does not support terminal IOCTLs (e.g. TCGETS, TCSETS, TIOCMSET, etc.). To make it possible to interact with the WWAN AT port using a terminal emulator, implement a minimal set of terminal IOCTLs. The implementation is rather stub, no passed data are actually used to control a port behaviour. An obtained configuration is kept inside the port structure and returned back by a request. The latter is done to fool a program that will test the configuration status by comparing the readed back data from the device with earlier configured ones. Tested with fresh versions of minicom and picocom terminal apps. MBIM, QMI and other ports for binary protocols can hardly be considered a terminal device, so terminal IOCTLs are only implemented for the AT port. Signed-off-by: Sergey Ryazanov --- drivers/net/wwan/wwan_core.c | 91 ++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/drivers/net/wwan/wwan_core.c b/drivers/net/wwan/wwan_core.c index d5a197da4a41..38da3124d81e 100644 --- a/drivers/net/wwan/wwan_core.c +++ b/drivers/net/wwan/wwan_core.c @@ -51,6 +51,8 @@ struct wwan_device { * @dev: Underlying device * @rxq: Buffer inbound queue * @waitqueue: The waitqueue for port fops (read/write/poll) + * @data_lock: Port specific data access serialization + * @at_data: AT port specific data */ struct wwan_port { enum wwan_port_type type; @@ -61,6 +63,13 @@ struct wwan_port { struct device dev; struct sk_buff_head rxq; wait_queue_head_t waitqueue; + struct mutex data_lock; /* Port specific data access serialization */ + union { + struct { + struct ktermios termios; + int mdmbits; + } at_data; + }; }; static ssize_t index_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -230,6 +239,7 @@ static void wwan_port_destroy(struct device *dev) struct wwan_port *port = to_wwan_port(dev); ida_free(&minors, MINOR(port->dev.devt)); + mutex_destroy(&port->data_lock); skb_queue_purge(&port->rxq); mutex_destroy(&port->ops_lock); kfree(port); @@ -344,6 +354,7 @@ struct wwan_port *wwan_create_port(struct device *parent, mutex_init(&port->ops_lock); skb_queue_head_init(&port->rxq); init_waitqueue_head(&port->waitqueue); + mutex_init(&port->data_lock); port->dev.parent = &wwandev->dev; port->dev.class = wwan_class; @@ -619,10 +630,90 @@ static __poll_t wwan_port_fops_poll(struct file *filp, poll_table *wait) return mask; } +/* Implements minimalistic stub terminal IOCTLs support */ +static long wwan_port_fops_at_ioctl(struct wwan_port *port, unsigned int cmd, + unsigned long arg) +{ + int ret = 0; + + mutex_lock(&port->data_lock); + + switch (cmd) { + case TCFLSH: + break; + + case TCGETS: + if (copy_to_user((void __user *)arg, &port->at_data.termios, + sizeof(struct termios))) + ret = -EFAULT; + break; + + case TCSETS: + case TCSETSW: + case TCSETSF: + if (copy_from_user(&port->at_data.termios, (void __user *)arg, + sizeof(struct termios))) + ret = -EFAULT; + break; + +#ifdef TCGETS2 + case TCGETS2: + if (copy_to_user((void __user *)arg, &port->at_data.termios, + sizeof(struct termios2))) + ret = -EFAULT; + break; + + case TCSETS2: + case TCSETSW2: + case TCSETSF2: + if (copy_from_user(&port->at_data.termios, (void __user *)arg, + sizeof(struct termios2))) + ret = -EFAULT; + break; +#endif + + case TIOCMGET: + ret = put_user(port->at_data.mdmbits, (int __user *)arg); + break; + + case TIOCMSET: + case TIOCMBIC: + case TIOCMBIS: { + int mdmbits; + + if (copy_from_user(&mdmbits, (int __user *)arg, sizeof(int))) { + ret = -EFAULT; + break; + } + if (cmd == TIOCMBIC) + port->at_data.mdmbits &= ~mdmbits; + else if (cmd == TIOCMBIS) + port->at_data.mdmbits |= mdmbits; + else + port->at_data.mdmbits = mdmbits; + break; + } + + default: + ret = -ENOIOCTLCMD; + } + + mutex_unlock(&port->data_lock); + + return ret; +} + static long wwan_port_fops_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct wwan_port *port = filp->private_data; + int res; + + if (port->type == WWAN_PORT_AT) { /* AT port specific IOCTLs */ + res = wwan_port_fops_at_ioctl(port, cmd, arg); + if (res != -ENOIOCTLCMD) + return res; + } switch (cmd) { case TIOCINQ: { /* aka SIOCINQ aka FIONREAD */ -- 2.26.3