Received: by 2002:a05:6a10:6744:0:0:0:0 with SMTP id w4csp330300pxu; Wed, 14 Oct 2020 02:26:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw++DLVvWW0hfBqsgIkZx/hT6xp7JZGKt7mJX+nEbN3B4BW8INxf8kVYNRq1gFKWSCmOaDZ X-Received: by 2002:a17:906:86ce:: with SMTP id j14mr4347893ejy.158.1602667618119; Wed, 14 Oct 2020 02:26:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1602667618; cv=none; d=google.com; s=arc-20160816; b=H0/vpGT6owaXYDiKrfJjKC+N55Ct8ngXbO/own/tJ/ThThSJMAB0cltdOiFNfLLcFl Nx+dtnfB/Cb7bzGoPbF2Awiokb8H9dCcZ6t0Ua5m6zrvR8iVTsSdo1Ee6Ohml6ZYfnTp B+El3KxhNXAa4/3HLoQcgNPIqN8hoVD0CNbVAzmi+PGeiSlQ2xrp2WNQ7JlRE3/zg+/B T5xzp6xxwop6cwVjBHSSS1CGFMswjFP9WkHkTO2Wff8rUvn2gPD0T7J+5EBO+qTxQh78 1jpPCnl7yfrQYH/5dZsKqAAhI8mEQkU6FHjHOLtMSBHEDKhYe26y8wobn59JlHW7E4qW rtmA== 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=l3Mt/0E9AmGeziRvZyZJfVySy927OsM82c2xG5wHBJ0=; b=cPIp2xzURvTUQ8O1/ZWkIQPw+cFfdbbZcbJTQ+GCBMxH6WAFEDtjrjQtIN3+363LNF Eb+xK0WyArGd/flrnHs2y8pcj33ke/nM/MXzgPq51jFPGmTprguNM70/KcPTXmresf8D pq6L7Ux4bcPJYys+ljTWO5ovsz8ta2WVM0+Gxfg77Ik9fWjQhmjvmfff9IEhF11/ZysU P5ghrTS4GNzzNkEnXHwuXS3bYHR0OReDd8XYTtA19t+g1b6JEmBzI6on3lKWHfkgMI5Z gkbdH/J/KPLJs5lLeYr1x+j86J++MBMf92OontbvnYPfDT31WhxOrl5nck9rh+W2HypU TCtQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=vfYybF6X; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id s3si1803734ejj.426.2020.10.14.02.26.36; Wed, 14 Oct 2020 02:26:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-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=@linaro.org header.s=google header.b=vfYybF6X; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730667AbgJNJYa (ORCPT + 99 others); Wed, 14 Oct 2020 05:24:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730813AbgJNJUK (ORCPT ); Wed, 14 Oct 2020 05:20:10 -0400 Received: from mail-pg1-x544.google.com (mail-pg1-x544.google.com [IPv6:2607:f8b0:4864:20::544]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C25A2C08EA7F for ; Tue, 13 Oct 2020 16:25:32 -0700 (PDT) Received: by mail-pg1-x544.google.com with SMTP id r10so716502pgb.10 for ; Tue, 13 Oct 2020 16:25:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=l3Mt/0E9AmGeziRvZyZJfVySy927OsM82c2xG5wHBJ0=; b=vfYybF6Xx0JLOBoKy7O795Xg8FWZlvzUUw3+rZbNAkKS20S6kK9UqruBKkRvb4NFTT S/JVwIEXLyhr4NhAg9LjErZNpknyoEcWy+uKGvjxLbYDEm30mdceLxutDoxM7tsjMkeJ ZX5NvHVVsFr750r8QTsZsi+hSKZprNApmk7Z0U2lISuY6a2lN5MyEHWWT8ogNr8e+Kf+ pgExKU4ko7atGtnhawaT2p2k/swPbGmc2kxlekEwKj9OQWgKinm1dGNm+Ckm+jvMvKg0 jG9R/edlQW/1xBEceYAfqfKfMgyXZfHeO99hzQKjZ/zbd7h8oyAYpGiF+p6ItWzo72ZY AghQ== 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=l3Mt/0E9AmGeziRvZyZJfVySy927OsM82c2xG5wHBJ0=; b=SZas9Ut4cQZ8eRADELrzdSorQd6RMxl7eMiLPOgexSvuOHrQS6TgbmnVxJnS9/wILw JpvzFZddllg73pi8rL78m6sBZJUVP9oS+216FTIQ/kpWkOymBOTXMctgO6iZcLGkUy4r nuEyp96fJw5rXjo7J9WkxbCr2jGWRJS6OnUnRhonNXheW69LEwAz0HF+vjA1XHLTyNh7 6vI3UMeIHO6py8f8J/+RFoqIkuYw9dGjNd3YkO346Tm3MFcAUEOIvAxNG6mCps4y/1bp VoYnwS8TlX3KvWXPjSW4k7PyZEAekVFvqP5+fiff0BtUFtIyK6Lcwx6Pp7Lv41FSSUvR sd6g== X-Gm-Message-State: AOAM5313RxJvWLXBQfQBQqeumKfpucka0p+bbSTRmeGo2iOqa0BsS9y0 K49lBrlf+enW9T5saTZ3rTb/AA== X-Received: by 2002:a63:f815:: with SMTP id n21mr1573710pgh.410.1602631532303; Tue, 13 Oct 2020 16:25:32 -0700 (PDT) Received: from xps15.cg.shawcable.net (S0106002369de4dac.cg.shawcable.net. [68.147.8.254]) by smtp.gmail.com with ESMTPSA id b8sm791871pfr.159.2020.10.13.16.25.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Oct 2020 16:25:31 -0700 (PDT) From: Mathieu Poirier To: ohad@wizery.com, bjorn.andersson@linaro.org Cc: guennadi.liakhovetski@linux.intel.com, arnaud.pouliquen@st.com, linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 9/9] rpmsg: Turn name service into a stand alone driver Date: Tue, 13 Oct 2020 17:25:19 -0600 Message-Id: <20201013232519.1367542-10-mathieu.poirier@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201013232519.1367542-1-mathieu.poirier@linaro.org> References: <20201013232519.1367542-1-mathieu.poirier@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Arnaud Pouliquen Make the RPMSG name service announcement a stand alone driver so that it can be reused by other subsystems. It is also the first step in making the functionatlity transport independent, i.e that is not tied to virtIO. Co-developed-by: Mathieu Poirier Signed-off-by: Arnaud Pouliquen --- drivers/rpmsg/Kconfig | 8 +++ drivers/rpmsg/Makefile | 1 + drivers/rpmsg/rpmsg_ns.c | 110 +++++++++++++++++++++++++++++++ drivers/rpmsg/virtio_rpmsg_bus.c | 84 +++++------------------ include/linux/rpmsg_ns.h | 17 +++++ 5 files changed, 154 insertions(+), 66 deletions(-) create mode 100644 drivers/rpmsg/rpmsg_ns.c diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig index f96716893c2a..c3fc75e6514b 100644 --- a/drivers/rpmsg/Kconfig +++ b/drivers/rpmsg/Kconfig @@ -15,6 +15,14 @@ config RPMSG_CHAR in /dev. They make it possible for user-space programs to send and receive rpmsg packets. +config RPMSG_NS + tristate "RPMSG name service announcement" + depends on RPMSG + help + Say Y here to enable the support of the name service announcement + channel that probes the associated RPMsg device on remote endpoint + service announcement. + config RPMSG_MTK_SCP tristate "MediaTek SCP" depends on MTK_SCP diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile index ffe932ef6050..8d452656f0ee 100644 --- a/drivers/rpmsg/Makefile +++ b/drivers/rpmsg/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_RPMSG) += rpmsg_core.o obj-$(CONFIG_RPMSG_CHAR) += rpmsg_char.o +obj-$(CONFIG_RPMSG_NS) += rpmsg_ns.o obj-$(CONFIG_RPMSG_MTK_SCP) += mtk_rpmsg.o qcom_glink-objs := qcom_glink_native.o qcom_glink_ssr.o obj-$(CONFIG_RPMSG_QCOM_GLINK) += qcom_glink.o diff --git a/drivers/rpmsg/rpmsg_ns.c b/drivers/rpmsg/rpmsg_ns.c new file mode 100644 index 000000000000..65be20583c8f --- /dev/null +++ b/drivers/rpmsg/rpmsg_ns.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) STMicroelectronics 2020 - All Rights Reserved + */ +#include +#include +#include +#include +#include +#include +#include + +#include "rpmsg_internal.h" + +/* invoked when a name service announcement arrives */ +static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len, + void *priv, u32 src) +{ + struct rpmsg_ns_msg *msg = data; + struct rpmsg_device *newch; + struct rpmsg_channel_info chinfo; + struct device *dev = rpdev->dev.parent; + int ret; + +#if defined(CONFIG_DYNAMIC_DEBUG) + dynamic_hex_dump("NS announcement: ", DUMP_PREFIX_NONE, 16, 1, + data, len, true); +#endif + + if (len != sizeof(*msg)) { + dev_err(dev, "malformed ns msg (%d)\n", len); + return -EINVAL; + } + + /* don't trust the remote processor for null terminating the name */ + msg->name[RPMSG_NAME_SIZE - 1] = '\0'; + + strncpy(chinfo.name, msg->name, sizeof(chinfo.name)); + chinfo.src = RPMSG_ADDR_ANY; + chinfo.dst = rpmsg32_to_cpu(rpdev, msg->addr); + + dev_info(dev, "%sing channel %s addr 0x%x\n", + rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY ? + "destroy" : "creat", msg->name, chinfo.dst); + + if (rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY) { + ret = rpmsg_release_channel(rpdev, &chinfo); + if (ret) + dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret); + } else { + newch = rpmsg_create_channel(rpdev, &chinfo); + if (!newch) + dev_err(dev, "rpmsg_create_channel failed\n"); + } + + return 0; +} + + +static int rpmsg_ns_probe(struct rpmsg_device *rpdev) +{ + struct rpmsg_endpoint *ns_ept; + struct rpmsg_channel_info ns_chinfo = { + .src = RPMSG_NS_ADDR, + .dst = RPMSG_NS_ADDR, + .name = "name_service", + }; + + /* + * Create the NS announcement service endpoint associated to the RPMsg + * device. The endpoint will be automatically destroyed when the RPMsg + * device will be deleted. + */ + ns_ept = rpmsg_create_ept(rpdev, rpmsg_ns_cb, NULL, ns_chinfo); + if (!ns_ept) { + dev_err(&rpdev->dev, "failed to create the ns ept\n"); + return -ENOMEM; + } + rpdev->ept = ns_ept; + + return 0; +} + +static struct rpmsg_driver rpmsg_ns_driver = { + .drv.name = "rpmsg_ns", + .probe = rpmsg_ns_probe, +}; + +static int rpmsg_ns_init(void) +{ + int ret; + + ret = register_rpmsg_driver(&rpmsg_ns_driver); + if (ret < 0) + pr_err("%s: Failed to register rpmsg driver\n", __func__); + + return ret; +} +postcore_initcall(rpmsg_ns_init); + +static void rpmsg_ns_exit(void) +{ + unregister_rpmsg_driver(&rpmsg_ns_driver); +} +module_exit(rpmsg_ns_exit); + +MODULE_DESCRIPTION("Name service announcement rpmsg Driver"); +MODULE_AUTHOR("Arnaud Pouliquen "); +MODULE_ALIAS("rpmsg_ns"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 1488b9ddc18d..a5284dc40ac5 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -49,7 +49,6 @@ * @endpoints_lock: lock of the endpoints set * @sendq: wait queue of sending contexts waiting for a tx buffers * @sleepers: number of senders that are waiting for a tx buffer - * @ns_ept: the bus's name service endpoint * * This structure stores the rpmsg state of a given virtio remote processor * device (there might be several virtio proc devices for each physical @@ -68,7 +67,6 @@ struct virtproc_info { struct mutex endpoints_lock; wait_queue_head_t sendq; atomic_t sleepers; - struct rpmsg_endpoint *ns_ept; }; /** @@ -794,68 +792,14 @@ static void rpmsg_xmit_done(struct virtqueue *svq) wake_up_interruptible(&vrp->sendq); } -/* invoked when a name service announcement arrives */ -static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len, - void *priv, u32 src) -{ - struct rpmsg_ns_msg *msg = data; - struct rpmsg_device *newch; - struct rpmsg_channel_info chinfo; - struct virtproc_info *vrp = priv; - struct device *dev = &vrp->vdev->dev; - int ret; - -#if defined(CONFIG_DYNAMIC_DEBUG) - dynamic_hex_dump("NS announcement: ", DUMP_PREFIX_NONE, 16, 1, - data, len, true); -#endif - - if (len != sizeof(*msg)) { - dev_err(dev, "malformed ns msg (%d)\n", len); - return -EINVAL; - } - - /* - * the name service ept does _not_ belong to a real rpmsg channel, - * and is handled by the rpmsg bus itself. - * for sanity reasons, make sure a valid rpdev has _not_ sneaked - * in somehow. - */ - if (rpdev) { - dev_err(dev, "anomaly: ns ept has an rpdev handle\n"); - return -EINVAL; - } - - /* don't trust the remote processor for null terminating the name */ - msg->name[RPMSG_NAME_SIZE - 1] = '\0'; - - strncpy(chinfo.name, msg->name, sizeof(chinfo.name)); - chinfo.src = RPMSG_ADDR_ANY; - chinfo.dst = rpmsg32_to_cpu(rpdev, msg->addr); - - dev_info(dev, "%sing channel %s addr 0x%x\n", - rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY ? - "destroy" : "creat", msg->name, chinfo.dst); - - if (rpmsg32_to_cpu(rpdev, msg->flags) & RPMSG_NS_DESTROY) { - ret = rpmsg_unregister_device(&vrp->vdev->dev, &chinfo); - if (ret) - dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret); - } else { - newch = __rpmsg_create_channel(vrp, &chinfo); - if (!newch) - dev_err(dev, "rpmsg_create_channel failed\n"); - } - - return 0; -} - static int rpmsg_probe(struct virtio_device *vdev) { vq_callback_t *vq_cbs[] = { rpmsg_recv_done, rpmsg_xmit_done }; static const char * const names[] = { "input", "output" }; struct virtqueue *vqs[2]; struct virtproc_info *vrp; + struct virtio_rpmsg_channel *vch; + struct rpmsg_device *rpdev_ns; void *bufs_va; int err = 0, i; size_t total_buf_space; @@ -931,14 +875,25 @@ static int rpmsg_probe(struct virtio_device *vdev) /* if supported by the remote processor, enable the name service */ if (virtio_has_feature(vdev, VIRTIO_RPMSG_F_NS)) { - /* a dedicated endpoint handles the name service msgs */ - vrp->ns_ept = __rpmsg_create_ept(vrp, NULL, rpmsg_ns_cb, - vrp, RPMSG_NS_ADDR); - if (!vrp->ns_ept) { - dev_err(&vdev->dev, "failed to create the ns ept\n"); + vch = kzalloc(sizeof(*vch), GFP_KERNEL); + if (!vch) { err = -ENOMEM; goto free_coherent; } + + /* Link the channel to our vrp */ + vch->vrp = vrp; + + /* Assign public information to the rpmsg_device */ + rpdev_ns = &vch->rpdev; + rpdev_ns->ops = &virtio_rpmsg_ops; + + rpdev_ns->dev.parent = &vrp->vdev->dev; + rpdev_ns->dev.release = virtio_rpmsg_release_device; + + err = rpmsg_ns_register_device(rpdev_ns); + if (err) + goto free_coherent; } /* @@ -991,9 +946,6 @@ static void rpmsg_remove(struct virtio_device *vdev) if (ret) dev_warn(&vdev->dev, "can't remove rpmsg device: %d\n", ret); - if (vrp->ns_ept) - __rpmsg_destroy_ept(vrp, vrp->ns_ept); - idr_destroy(&vrp->endpoints); vdev->config->del_vqs(vrp->vdev); diff --git a/include/linux/rpmsg_ns.h b/include/linux/rpmsg_ns.h index 3d836b8580b2..9e529ef40ce5 100644 --- a/include/linux/rpmsg_ns.h +++ b/include/linux/rpmsg_ns.h @@ -59,4 +59,21 @@ enum rpmsg_ns_flags { /* Address 53 is reserved for advertising remote services */ #define RPMSG_NS_ADDR (53) +/** + * rpmsg_ns_register_device() - register name service device based on rpdev + * @rpdev: prepared rpdev to be used for creating endpoints + * + * This function wraps rpmsg_register_device() preparing the rpdev for use as + * basis for the rpmsg name service device. + */ +static inline int rpmsg_ns_register_device(struct rpmsg_device *rpdev) +{ + strcpy(rpdev->id.name, "rpmsg_ns"); + rpdev->driver_override = "rpmsg_ns"; + rpdev->src = RPMSG_NS_ADDR; + rpdev->dst = RPMSG_NS_ADDR; + + return rpmsg_register_device(rpdev); +} + #endif -- 2.25.1