Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp4666430pxk; Wed, 30 Sep 2020 08:39:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxYP2OBozXLene5yedsHKM0wu4BNP8OBTWqZOeIcrLAsjz1sWLfEopen4yQQpBRXZOKWZUI X-Received: by 2002:a05:6402:1515:: with SMTP id f21mr3493481edw.175.1601480370828; Wed, 30 Sep 2020 08:39:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1601480370; cv=none; d=google.com; s=arc-20160816; b=ErtVkht5y/ooPStm4XC6astcJKDJoXEB3nO1lQ9SN/cch9JD7Jw44N56SeQ0ghAovw PNQ6Mw/XKsOrJwYMb1CZnGyevopCTUHA6495Y4ytgw7WX6+IGymAcaEqVBzhs5w+0UnW goWz1EfguupEqKQBE5iYmSXzqBh5BGtAQ4divB/rON6XGEtgpt0PP0Rk0NglpAZaH4UR ToEg2h6ckJHwk7VPAn1siSIbBpcIbgvLnlSlu1oELuOObMw1ggQ/0ZkLfReDC033xEVL V5Vc0fOtdliYpPWSE/JNaacgcuYS7kW5J0VGvyCR72H9F29sZe7Jtp3n+vm7k/kLTCXL v8hg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=z3Tw9eXfcOK90ruy3aMeRyVdcSzDrEL/G+eXeTQ/vG0=; b=Xsvm6Da6pKTWBz1GLe/CdrHpxqllc8Ws5xEif22dqL+mCRb4zBkQWkOsl0uZFyv602 sTrRTHHFTfPXgTb4bmTNTwZpLA3pXo5Av5WQc1fJhzl1f4/32RwsczcNUabgw1TtHWK5 SSlVy1uuWmFdVs0bLkBHt3iVzkIK32X8pivIEc1h+/HQobm5Wps0+HDOB67vv13n4TFg kV38OP0SgJeWDrMtXbc3uNB8Fl3mVIeHNtsn+vEhSeMVdlFOuxhA/FCm2jmNRHUW8Ops QXnbynBxMZpzq08diDgy+jGS8Pah2Wz99IIdlA5S3CY0veJeURAMhEGmx4KsmzUX+19u 90xQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=GjIfqWBC; 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=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id p13si1442218ejx.235.2020.09.30.08.39.06; Wed, 30 Sep 2020 08:39:30 -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=@ti.com header.s=ti-com-17Q1 header.b=GjIfqWBC; 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=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725893AbgI3Pgc (ORCPT + 99 others); Wed, 30 Sep 2020 11:36:32 -0400 Received: from fllv0016.ext.ti.com ([198.47.19.142]:47540 "EHLO fllv0016.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725372AbgI3Pgb (ORCPT ); Wed, 30 Sep 2020 11:36:31 -0400 Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 08UFaHED076608; Wed, 30 Sep 2020 10:36:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1601480177; bh=z3Tw9eXfcOK90ruy3aMeRyVdcSzDrEL/G+eXeTQ/vG0=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=GjIfqWBCmFwNJale9KF6i5o7bJIZExlNFNaAsFHe0OYnr+gigMOmdgqUsQXR5F4Oj CXNJEO+xDYQa67O/3tTVJqpu+ceRW/j4K9NtmWl/vRDrB2IQF4RQBPNPInZglYVozt D1JOJXVT6lcrZ9/vQgzvMqY9+l5iAE+63YhdaPxo= Received: from DLEE106.ent.ti.com (dlee106.ent.ti.com [157.170.170.36]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 08UFaH3p024387 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 30 Sep 2020 10:36:17 -0500 Received: from DLEE100.ent.ti.com (157.170.170.30) by DLEE106.ent.ti.com (157.170.170.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Wed, 30 Sep 2020 10:36:17 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Wed, 30 Sep 2020 10:36:17 -0500 Received: from a0393678-ssd.dal.design.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 08UFZLZW033254; Wed, 30 Sep 2020 10:36:03 -0500 From: Kishon Vijay Abraham I To: Bjorn Helgaas , Jonathan Corbet , Kishon Vijay Abraham I , Lorenzo Pieralisi , Arnd Bergmann , Jon Mason , Dave Jiang , Allen Hubbe , Tom Joseph , Rob Herring CC: Greg Kroah-Hartman , , , , Subject: [PATCH v7 07/18] PCI: endpoint: Add support in configfs to associate two EPCs with EPF Date: Wed, 30 Sep 2020 21:05:08 +0530 Message-ID: <20200930153519.7282-8-kishon@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200930153519.7282-1-kishon@ti.com> References: <20200930153519.7282-1-kishon@ti.com> MIME-Version: 1.0 Content-Type: text/plain X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Now that PCI endpoint core supports to add secondary endpoint controller (EPC) with endpoint function (EPF), Add support in configfs to associate two EPCs with EPF. This creates "primary" and "secondary" directory inside the directory created by users for EPF device. Users have to add a symlink of endpoint controller (pci_ep/controllers/) to "primary" or "secondary" directory to bind EPF to primary and secondary EPF interfaces respectively. Existing method of linking directory representing EPF device to directory representing EPC device to associate a single EPC device with a EPF device will continue to work. Signed-off-by: Kishon Vijay Abraham I --- .../PCI/endpoint/pci-endpoint-cfs.rst | 10 ++ drivers/pci/endpoint/pci-ep-cfs.c | 147 ++++++++++++++++++ 2 files changed, 157 insertions(+) diff --git a/Documentation/PCI/endpoint/pci-endpoint-cfs.rst b/Documentation/PCI/endpoint/pci-endpoint-cfs.rst index 1bbd81ed06c8..696f8eeb4738 100644 --- a/Documentation/PCI/endpoint/pci-endpoint-cfs.rst +++ b/Documentation/PCI/endpoint/pci-endpoint-cfs.rst @@ -68,6 +68,16 @@ created) ... subsys_vendor_id ... subsys_id ... interrupt_pin + ... primary/ + ... / + ... secondary/ + ... / + +If an EPF device has to be associated with 2 EPCs (like in the case of +Non-transparent bridge), symlink of endpoint controller connected to primary +interface should be added in 'primary' directory and symlink of endpoint +controller connected to secondary interface should be added in 'secondary' +directory. EPC Device ========== diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index 6ca9e2f92460..8f750961d6ab 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -21,6 +21,9 @@ static struct config_group *controllers_group; struct pci_epf_group { struct config_group group; + struct config_group primary_epc_group; + struct config_group secondary_epc_group; + struct delayed_work cfs_work; struct pci_epf *epf; int index; }; @@ -41,6 +44,127 @@ static inline struct pci_epc_group *to_pci_epc_group(struct config_item *item) return container_of(to_config_group(item), struct pci_epc_group, group); } +static int pci_secondary_epc_epf_link(struct config_item *epf_item, + struct config_item *epc_item) +{ + int ret; + struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent); + struct pci_epc_group *epc_group = to_pci_epc_group(epc_item); + struct pci_epc *epc = epc_group->epc; + struct pci_epf *epf = epf_group->epf; + + ret = pci_epc_add_epf(epc, epf, SECONDARY_INTERFACE); + if (ret) + return ret; + + ret = pci_epf_bind(epf); + if (ret) { + pci_epc_remove_epf(epc, epf, SECONDARY_INTERFACE); + return ret; + } + + return 0; +} + +static void pci_secondary_epc_epf_unlink(struct config_item *epc_item, + struct config_item *epf_item) +{ + struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent); + struct pci_epc_group *epc_group = to_pci_epc_group(epc_item); + struct pci_epc *epc; + struct pci_epf *epf; + + WARN_ON_ONCE(epc_group->start); + + epc = epc_group->epc; + epf = epf_group->epf; + pci_epf_unbind(epf); + pci_epc_remove_epf(epc, epf, SECONDARY_INTERFACE); +} + +static struct configfs_item_operations pci_secondary_epc_item_ops = { + .allow_link = pci_secondary_epc_epf_link, + .drop_link = pci_secondary_epc_epf_unlink, +}; + +static const struct config_item_type pci_secondary_epc_type = { + .ct_item_ops = &pci_secondary_epc_item_ops, + .ct_owner = THIS_MODULE, +}; + +static struct config_group +*pci_ep_cfs_add_secondary_group(struct pci_epf_group *epf_group) +{ + struct config_group *secondary_epc_group; + + secondary_epc_group = &epf_group->secondary_epc_group; + config_group_init_type_name(secondary_epc_group, "secondary", + &pci_secondary_epc_type); + configfs_register_group(&epf_group->group, secondary_epc_group); + + return secondary_epc_group; +} + +static int pci_primary_epc_epf_link(struct config_item *epf_item, + struct config_item *epc_item) +{ + int ret; + struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent); + struct pci_epc_group *epc_group = to_pci_epc_group(epc_item); + struct pci_epc *epc = epc_group->epc; + struct pci_epf *epf = epf_group->epf; + + ret = pci_epc_add_epf(epc, epf, PRIMARY_INTERFACE); + if (ret) + return ret; + + ret = pci_epf_bind(epf); + if (ret) { + pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE); + return ret; + } + + return 0; +} + +static void pci_primary_epc_epf_unlink(struct config_item *epc_item, + struct config_item *epf_item) +{ + struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent); + struct pci_epc_group *epc_group = to_pci_epc_group(epc_item); + struct pci_epc *epc; + struct pci_epf *epf; + + WARN_ON_ONCE(epc_group->start); + + epc = epc_group->epc; + epf = epf_group->epf; + pci_epf_unbind(epf); + pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE); +} + +static struct configfs_item_operations pci_primary_epc_item_ops = { + .allow_link = pci_primary_epc_epf_link, + .drop_link = pci_primary_epc_epf_unlink, +}; + +static const struct config_item_type pci_primary_epc_type = { + .ct_item_ops = &pci_primary_epc_item_ops, + .ct_owner = THIS_MODULE, +}; + +static struct config_group +*pci_ep_cfs_add_primary_group(struct pci_epf_group *epf_group) +{ + struct config_group *primary_epc_group = &epf_group->primary_epc_group; + + config_group_init_type_name(primary_epc_group, "primary", + &pci_primary_epc_type); + configfs_register_group(&epf_group->group, primary_epc_group); + + return primary_epc_group; +} + static ssize_t pci_epc_start_store(struct config_item *item, const char *page, size_t len) { @@ -372,6 +496,25 @@ static const struct config_item_type pci_epf_type = { .ct_owner = THIS_MODULE, }; +static void pci_epf_cfs_work(struct work_struct *work) +{ + struct pci_epf_group *epf_group; + struct config_group *group; + + epf_group = container_of(work, struct pci_epf_group, cfs_work.work); + group = pci_ep_cfs_add_primary_group(epf_group); + if (IS_ERR(group)) { + pr_err("failed to create 'primary' EPC interface\n"); + return; + } + + group = pci_ep_cfs_add_secondary_group(epf_group); + if (IS_ERR(group)) { + pr_err("failed to create 'secondary' EPC interface\n"); + return; + } +} + static struct config_group *pci_epf_make(struct config_group *group, const char *name) { @@ -414,6 +557,10 @@ static struct config_group *pci_epf_make(struct config_group *group, kfree(epf_name); + INIT_DELAYED_WORK(&epf_group->cfs_work, pci_epf_cfs_work); + queue_delayed_work(system_wq, &epf_group->cfs_work, + msecs_to_jiffies(1)); + return &epf_group->group; free_name: -- 2.17.1