From patchwork Mon Jun 7 18:21:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ameynarkhede03 X-Patchwork-Id: 12304419 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8FCDBC47082 for ; Mon, 7 Jun 2021 18:23:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7AB906100B for ; Mon, 7 Jun 2021 18:23:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230267AbhFGSZS (ORCPT ); Mon, 7 Jun 2021 14:25:18 -0400 Received: from mail-pj1-f54.google.com ([209.85.216.54]:55902 "EHLO mail-pj1-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230404AbhFGSZR (ORCPT ); Mon, 7 Jun 2021 14:25:17 -0400 Received: by mail-pj1-f54.google.com with SMTP id k7so10376192pjf.5; Mon, 07 Jun 2021 11:23:26 -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=VqQOpJKxzJ4iXeJuu/O3h8CrpjPwv08YHWrIZDj9y8w=; b=UhVtkOrf8h3YD5jYJPMreHL+BTACBxsBowp8rbmH0bPN0cu5a2w0YWBX8WzKe/xuXb kE6mP3/CT3NBRaT7uyIqvmyxa7umr3i1JaD9YmJENoUfkJumj1r20QAoNPpZSpE8UTNg Zb9To9lcv8Tgfc1Iujl0iDOqx6FvPtMnJRYyxwrP+a/dpdAxEHUE5RkFYgRfPJUI5v0I gG3mL/jvGmSxDphTDPn/g/KOOo5pDpCLMXE0N17iyYnSi708/M+myV2Sgt/2x9dCzN36 I44G4XdQr2MoDGjCncrG8quP62yz81h/IgA4e7FQNVDodx+yGlu57dfXVqjJvaqaEDzA /HBw== 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=VqQOpJKxzJ4iXeJuu/O3h8CrpjPwv08YHWrIZDj9y8w=; b=bnFY1eGOP6wxDOQqbSSkQdP5SCfndEAlB8jW/kza8eqDDRzooBXGF2Sc52dzM6KtVH Terfk5OQ8BXWadAL1xdTnwgyZLaO5gH56FmcRB1nc1kE8x8l52F6AW+M4LvHlg7KlRlr dYndI2+/nJdGW6xmffYeawq+D5r6DOh0zlmwI/ArYYPbGBIv5rXutpknTy1k4mCO5TRz AuNzjUVdjNUjDay85eWM4xgmmCtXH9FALOkHEaReYlfDX56rZ78x6WbDVEVuYOnGavvf R/1lYMpb28nAm0LXUXnb50wtTuQsJcUvw1kjDOnSE95V5RfZN9J4wjSS3YGHGQZozkwD WCcQ== X-Gm-Message-State: AOAM531o0Mk3EwRdn9rhW63DfrHpJRAaYziaFhQN5gfC9AwJKUaS4xUD dt3bHJIGa6vuK87aaDNq/ws= X-Google-Smtp-Source: ABdhPJwVJ24itLA60f9hv2N8GulmTtsjsA5UTSDXS+lhHBW7nXR9Fb99XhZrdU+SqRRhFu0dowTrHA== X-Received: by 2002:a17:902:8ec4:b029:fb:33ad:e86f with SMTP id x4-20020a1709028ec4b02900fb33ade86fmr19108451plo.4.1623090146101; Mon, 07 Jun 2021 11:22:26 -0700 (PDT) Received: from localhost.localdomain ([103.200.106.115]) by smtp.googlemail.com with ESMTPSA id k1sm8687656pfa.30.2021.06.07.11.22.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Jun 2021 11:22:25 -0700 (PDT) From: Amey Narkhede To: Bjorn Helgaas Cc: alex.williamson@redhat.com, Raphael Norwitz , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, kw@linux.com, Shanker Donthineni , Sinan Kaya , Amey Narkhede Subject: [PATCH v6 1/8] PCI: Add pcie_reset_flr to follow calling convention of other reset methods Date: Mon, 7 Jun 2021 23:51:30 +0530 Message-Id: <20210607182137.5794-2-ameynarkhede03@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210607182137.5794-1-ameynarkhede03@gmail.com> References: <20210607182137.5794-1-ameynarkhede03@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Currently there is separate function pcie_has_flr() to probe if pcie flr is supported by the device which does not match the calling convention followed by reset methods which use second function argument to decide whether to probe or not. Add new function pcie_reset_flr() that follows the calling convention of reset methods. Reviewed-by: Alex Williamson Reviewed-by: Raphael Norwitz Co-developed-by: Alex Williamson Signed-off-by: Alex Williamson Signed-off-by: Amey Narkhede --- drivers/crypto/cavium/nitrox/nitrox_main.c | 4 +- drivers/pci/pci.c | 62 ++++++++++++---------- drivers/pci/pcie/aer.c | 12 ++--- drivers/pci/quirks.c | 9 ++-- include/linux/pci.h | 2 +- 5 files changed, 43 insertions(+), 46 deletions(-) diff --git a/drivers/crypto/cavium/nitrox/nitrox_main.c b/drivers/crypto/cavium/nitrox/nitrox_main.c index facc8e6bc..15d6c8452 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_main.c +++ b/drivers/crypto/cavium/nitrox/nitrox_main.c @@ -306,9 +306,7 @@ static int nitrox_device_flr(struct pci_dev *pdev) return -ENOMEM; } - /* check flr support */ - if (pcie_has_flr(pdev)) - pcie_flr(pdev); + pcie_reset_flr(pdev, 0); pci_restore_state(pdev); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 452351025..3bf36924c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4611,32 +4611,12 @@ int pci_wait_for_pending_transaction(struct pci_dev *dev) } EXPORT_SYMBOL(pci_wait_for_pending_transaction); -/** - * pcie_has_flr - check if a device supports function level resets - * @dev: device to check - * - * Returns true if the device advertises support for PCIe function level - * resets. - */ -bool pcie_has_flr(struct pci_dev *dev) -{ - u32 cap; - - if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET) - return false; - - pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); - return cap & PCI_EXP_DEVCAP_FLR; -} -EXPORT_SYMBOL_GPL(pcie_has_flr); - /** * pcie_flr - initiate a PCIe function level reset * @dev: device to reset * - * Initiate a function level reset on @dev. The caller should ensure the - * device supports FLR before calling this function, e.g. by using the - * pcie_has_flr() helper. + * Initiate a function level reset unconditionally on @dev without + * checking any flags and DEVCAP */ int pcie_flr(struct pci_dev *dev) { @@ -4659,6 +4639,31 @@ int pcie_flr(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pcie_flr); +/** + * pcie_reset_flr - initiate a PCIe function level reset + * @dev: device to reset + * @probe: If set, only check if the device can be reset this way. + * + * Initiate a function level reset on @dev. + */ +int pcie_reset_flr(struct pci_dev *dev, int probe) +{ + u32 cap; + + if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET) + return -ENOTTY; + + pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); + if (!(cap & PCI_EXP_DEVCAP_FLR)) + return -ENOTTY; + + if (probe) + return 0; + + return pcie_flr(dev); +} +EXPORT_SYMBOL_GPL(pcie_reset_flr); + static int pci_af_flr(struct pci_dev *dev, int probe) { int pos; @@ -5139,11 +5144,9 @@ int __pci_reset_function_locked(struct pci_dev *dev) rc = pci_dev_specific_reset(dev, 0); if (rc != -ENOTTY) return rc; - if (pcie_has_flr(dev)) { - rc = pcie_flr(dev); - if (rc != -ENOTTY) - return rc; - } + rc = pcie_reset_flr(dev, 0); + if (rc != -ENOTTY) + return rc; rc = pci_af_flr(dev, 0); if (rc != -ENOTTY) return rc; @@ -5174,8 +5177,9 @@ int pci_probe_reset_function(struct pci_dev *dev) rc = pci_dev_specific_reset(dev, 1); if (rc != -ENOTTY) return rc; - if (pcie_has_flr(dev)) - return 0; + rc = pcie_reset_flr(dev, 1); + if (rc != -ENOTTY) + return rc; rc = pci_af_flr(dev, 1); if (rc != -ENOTTY) return rc; diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index ec943cee5..98077595a 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -1405,13 +1405,11 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) } if (type == PCI_EXP_TYPE_RC_EC || type == PCI_EXP_TYPE_RC_END) { - if (pcie_has_flr(dev)) { - rc = pcie_flr(dev); - pci_info(dev, "has been reset (%d)\n", rc); - } else { - pci_info(dev, "not reset (no FLR support)\n"); - rc = -ENOTTY; - } + rc = pcie_reset_flr(dev, 0); + if (!rc) + pci_info(dev, "has been reset\n"); + else + pci_info(dev, "not reset (no FLR support: %d)\n", rc); } else { rc = pci_bus_error_reset(dev); pci_info(dev, "%s Port link has been reset (%d)\n", diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index d85914afe..f977ba79a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3819,7 +3819,7 @@ static int nvme_disable_and_flr(struct pci_dev *dev, int probe) u32 cfg; if (dev->class != PCI_CLASS_STORAGE_EXPRESS || - !pcie_has_flr(dev) || !pci_resource_start(dev, 0)) + pcie_reset_flr(dev, 1) || !pci_resource_start(dev, 0)) return -ENOTTY; if (probe) @@ -3888,13 +3888,10 @@ static int nvme_disable_and_flr(struct pci_dev *dev, int probe) */ static int delay_250ms_after_flr(struct pci_dev *dev, int probe) { - if (!pcie_has_flr(dev)) - return -ENOTTY; + int ret = pcie_reset_flr(dev, probe); if (probe) - return 0; - - pcie_flr(dev); + return ret; msleep(250); diff --git a/include/linux/pci.h b/include/linux/pci.h index c20211e59..20b90c205 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1225,7 +1225,7 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev, enum pci_bus_speed *speed, enum pcie_link_width *width); void pcie_print_link_status(struct pci_dev *dev); -bool pcie_has_flr(struct pci_dev *dev); +int pcie_reset_flr(struct pci_dev *dev, int probe); int pcie_flr(struct pci_dev *dev); int __pci_reset_function_locked(struct pci_dev *dev); int pci_reset_function(struct pci_dev *dev); From patchwork Mon Jun 7 18:21:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ameynarkhede03 X-Patchwork-Id: 12304415 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AAF4CC47082 for ; Mon, 7 Jun 2021 18:22:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9159F61105 for ; Mon, 7 Jun 2021 18:22:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230507AbhFGSYh (ORCPT ); Mon, 7 Jun 2021 14:24:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48804 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230316AbhFGSYg (ORCPT ); Mon, 7 Jun 2021 14:24:36 -0400 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7057FC061787; Mon, 7 Jun 2021 11:22:30 -0700 (PDT) Received: by mail-pl1-x62c.google.com with SMTP id b12so3215016plg.11; Mon, 07 Jun 2021 11:22:30 -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=aAcRFUtR3ofinSM/RLsLfvOR2Fccz0rm5mzFFvQ1VLI=; b=nEfTimUGb1sGIl7eYYFRO3yVa28xu5yvFOCkid+jS2Bbn3bntMn6VhUcGH2XcnoMFV arczLUFaTSw1QL5dw81ZCT1wiLCgFmuNgm4ZHb6I6w7Y2m1XVwF4vw496LIeJgAuBsqE JGRSpbFJIku6Hl3v2gkJMXDKVeiZ+wBPnU8c48U5P8ENvGOVW4HoMtM338/hdZmJXqA8 P2k/EP/AdJTzr6qe2z6U8svRVtIm/sOd4n7u7iuE+knwD04qOufeM7VllrYoWYfHTsXK 7z0A1auOuDKBcHrfiJAE3wOo5Mb3OmDR6wEBbDYo4McEsABhUE/1WYGsmPInahTTVb8M +e9Q== 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=aAcRFUtR3ofinSM/RLsLfvOR2Fccz0rm5mzFFvQ1VLI=; b=fTlG5QV82zYBoVnc4efmsfI5JTw9QReoMiSJQdNfYHW02vqYpylM7YBsCWfKMt+myg fMcqKGa6KbrPlpjUw9Gl9pr4HbAGxa1hl50xfnk9MJo6sf76wReJT5VMYZF+PfsV5hBS IAECCb8LijPMEy2ulJUzcbukY+ZQ2Z79qxlMsv0/Nx208AtBR1kHZJ2y8fp9uAKHDQLb IfLbWtfPkZVoooI7SjCJleURhLT0dNL2eRxa8A1MKKvcnGv6uoMzQjhK0+WpDUmvUgrB bHpV4DfRkwMH1V4R8M41iNbytUi/CCcLqvzHzNHuXfb0tqS5Mz2tqZRDBWq5/phH8ovy knwg== X-Gm-Message-State: AOAM531U2LpHGp7iJmDjbKd3TClgyIDY4ZDHO8VPACbEU058mK/xKXIB ORuAEpr5d6liFLuLWPtdSZo= X-Google-Smtp-Source: ABdhPJxUhBHfgpV6jDeJ0DskbPuomepvl2T1cis58aNJJ66blmJH3f5C52G6e21YhAGyUuJkgucKBw== X-Received: by 2002:a17:90a:950c:: with SMTP id t12mr414726pjo.135.1623090149760; Mon, 07 Jun 2021 11:22:29 -0700 (PDT) Received: from localhost.localdomain ([103.200.106.115]) by smtp.googlemail.com with ESMTPSA id k1sm8687656pfa.30.2021.06.07.11.22.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Jun 2021 11:22:29 -0700 (PDT) From: Amey Narkhede To: Bjorn Helgaas Cc: alex.williamson@redhat.com, Raphael Norwitz , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, kw@linux.com, Shanker Donthineni , Sinan Kaya , Amey Narkhede Subject: [PATCH v6 2/8] PCI: Add new array for keeping track of ordering of reset methods Date: Mon, 7 Jun 2021 23:51:31 +0530 Message-Id: <20210607182137.5794-3-ameynarkhede03@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210607182137.5794-1-ameynarkhede03@gmail.com> References: <20210607182137.5794-1-ameynarkhede03@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Introduce a new array reset_methods in struct pci_dev to keep track of reset mechanisms supported by the device and their ordering. Also refactor probing and reset functions to take advantage of calling convention of reset functions. Reviewed-by: Alex Williamson Reviewed-by: Raphael Norwitz Co-developed-by: Alex Williamson Signed-off-by: Alex Williamson Signed-off-by: Amey Narkhede --- drivers/pci/pci.c | 108 ++++++++++++++++++++++++++------------------ drivers/pci/pci.h | 8 +++- drivers/pci/probe.c | 5 +- include/linux/pci.h | 7 +++ 4 files changed, 81 insertions(+), 47 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 3bf36924c..39a9ea8bb 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -72,6 +72,14 @@ static void pci_dev_d3_sleep(struct pci_dev *dev) msleep(delay); } +bool pci_reset_supported(struct pci_dev *dev) +{ + u8 null_reset_methods[PCI_RESET_METHODS_NUM] = { 0 }; + + return memcmp(null_reset_methods, + dev->reset_methods, PCI_RESET_METHODS_NUM); +} + #ifdef CONFIG_PCI_DOMAINS int pci_domains_supported = 1; #endif @@ -5107,6 +5115,18 @@ static void pci_dev_restore(struct pci_dev *dev) err_handler->reset_done(dev); } +/* + * The ordering for functions in pci_reset_fn_methods is required for + * reset_methods byte array defined in struct pci_dev. + */ +const struct pci_reset_fn_method pci_reset_fn_methods[] = { + { &pci_dev_specific_reset, .name = "device_specific" }, + { &pcie_reset_flr, .name = "flr" }, + { &pci_af_flr, .name = "af_flr" }, + { &pci_pm_reset, .name = "pm" }, + { &pci_reset_bus_function, .name = "bus" }, +}; + /** * __pci_reset_function_locked - reset a PCI device function while holding * the @dev mutex lock. @@ -5129,65 +5149,67 @@ static void pci_dev_restore(struct pci_dev *dev) */ int __pci_reset_function_locked(struct pci_dev *dev) { - int rc; + int i, rc = -ENOTTY; + u8 prio; might_sleep(); - /* - * A reset method returns -ENOTTY if it doesn't support this device - * and we should try the next method. - * - * If it returns 0 (success), we're finished. If it returns any - * other error, we're also finished: this indicates that further - * reset mechanisms might be broken on the device. - */ - rc = pci_dev_specific_reset(dev, 0); - if (rc != -ENOTTY) - return rc; - rc = pcie_reset_flr(dev, 0); - if (rc != -ENOTTY) - return rc; - rc = pci_af_flr(dev, 0); - if (rc != -ENOTTY) - return rc; - rc = pci_pm_reset(dev, 0); - if (rc != -ENOTTY) - return rc; - return pci_reset_bus_function(dev, 0); + for (prio = PCI_RESET_METHODS_NUM; prio; prio--) { + for (i = 0; i < PCI_RESET_METHODS_NUM; i++) { + if (dev->reset_methods[i] == prio) { + /* + * A reset method returns -ENOTTY if it doesn't + * support this device and we should try the + * next method. + * + * If it returns 0 (success), we're finished. + * If it returns any other error, we're also + * finished: this indicates that further reset + * mechanisms might be broken on the device. + */ + rc = pci_reset_fn_methods[i].reset_fn(dev, 0); + if (rc != -ENOTTY) + return rc; + break; + } + } + if (i == PCI_RESET_METHODS_NUM) + break; + } + return rc; } EXPORT_SYMBOL_GPL(__pci_reset_function_locked); /** - * pci_probe_reset_function - check whether the device can be safely reset - * @dev: PCI device to reset + * pci_init_reset_methods - check whether device can be safely reset + * and store supported reset mechanisms. + * @dev: PCI device to check for reset mechanisms * * Some devices allow an individual function to be reset without affecting * other functions in the same device. The PCI device must be responsive - * to PCI config space in order to use this function. + * to reads and writes to its PCI config space in order to use this function. * - * Returns 0 if the device function can be reset or negative if the - * device doesn't support resetting a single function. + * Stores reset mechanisms supported by device in reset_methods byte array + * which is a member of struct pci_dev. */ -int pci_probe_reset_function(struct pci_dev *dev) +void pci_init_reset_methods(struct pci_dev *dev) { - int rc; + int i, rc; + u8 prio = PCI_RESET_METHODS_NUM; + u8 reset_methods[PCI_RESET_METHODS_NUM] = { 0 }; - might_sleep(); + BUILD_BUG_ON(ARRAY_SIZE(pci_reset_fn_methods) != PCI_RESET_METHODS_NUM); - rc = pci_dev_specific_reset(dev, 1); - if (rc != -ENOTTY) - return rc; - rc = pcie_reset_flr(dev, 1); - if (rc != -ENOTTY) - return rc; - rc = pci_af_flr(dev, 1); - if (rc != -ENOTTY) - return rc; - rc = pci_pm_reset(dev, 1); - if (rc != -ENOTTY) - return rc; + might_sleep(); - return pci_reset_bus_function(dev, 1); + for (i = 0; i < PCI_RESET_METHODS_NUM; i++) { + rc = pci_reset_fn_methods[i].reset_fn(dev, 1); + if (!rc) + reset_methods[i] = prio--; + else if (rc != -ENOTTY) + break; + } + memcpy(dev->reset_methods, reset_methods, sizeof(reset_methods)); } /** diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 37c913bbc..13ec6bd6f 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -33,7 +33,7 @@ enum pci_mmap_api { int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vmai, enum pci_mmap_api mmap_api); -int pci_probe_reset_function(struct pci_dev *dev); +void pci_init_reset_methods(struct pci_dev *dev); int pci_bridge_secondary_bus_reset(struct pci_dev *dev); int pci_bus_error_reset(struct pci_dev *dev); @@ -606,6 +606,12 @@ struct pci_dev_reset_methods { int (*reset)(struct pci_dev *dev, int probe); }; +struct pci_reset_fn_method { + int (*reset_fn)(struct pci_dev *pdev, int probe); + char *name; +}; + +extern const struct pci_reset_fn_method pci_reset_fn_methods[]; #ifdef CONFIG_PCI_QUIRKS int pci_dev_specific_reset(struct pci_dev *dev, int probe); #else diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 3a62d09b8..8cf532681 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2404,9 +2404,8 @@ static void pci_init_capabilities(struct pci_dev *dev) pci_rcec_init(dev); /* Root Complex Event Collector */ pcie_report_downtraining(dev); - - if (pci_probe_reset_function(dev) == 0) - dev->reset_fn = 1; + pci_init_reset_methods(dev); + dev->reset_fn = pci_reset_supported(dev); } /* diff --git a/include/linux/pci.h b/include/linux/pci.h index 20b90c205..0955246f8 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -49,6 +49,8 @@ PCI_STATUS_SIG_TARGET_ABORT | \ PCI_STATUS_PARITY) +#define PCI_RESET_METHODS_NUM 5 + /* * The PCI interface treats multi-function devices as independent * devices. The slot/function address of each device is encoded @@ -505,6 +507,10 @@ struct pci_dev { char *driver_override; /* Driver name to force a match */ unsigned long priv_flags; /* Private flags for the PCI driver */ + /* + * See pci_reset_fn_methods array in pci.c for ordering. + */ + u8 reset_methods[PCI_RESET_METHODS_NUM]; /* Reset methods ordered by priority */ }; static inline struct pci_dev *pci_physfn(struct pci_dev *dev) @@ -1227,6 +1233,7 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev, void pcie_print_link_status(struct pci_dev *dev); int pcie_reset_flr(struct pci_dev *dev, int probe); int pcie_flr(struct pci_dev *dev); +bool pci_reset_supported(struct pci_dev *dev); int __pci_reset_function_locked(struct pci_dev *dev); int pci_reset_function(struct pci_dev *dev); int pci_reset_function_locked(struct pci_dev *dev); From patchwork Mon Jun 7 18:21:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ameynarkhede03 X-Patchwork-Id: 12304421 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D0EDAC47082 for ; Mon, 7 Jun 2021 18:23:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AD75F61003 for ; Mon, 7 Jun 2021 18:23:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230365AbhFGSZf (ORCPT ); Mon, 7 Jun 2021 14:25:35 -0400 Received: from mail-pl1-f173.google.com ([209.85.214.173]:41884 "EHLO mail-pl1-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230333AbhFGSZe (ORCPT ); Mon, 7 Jun 2021 14:25:34 -0400 Received: by mail-pl1-f173.google.com with SMTP id o12so5813113plk.8; Mon, 07 Jun 2021 11:23:33 -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=PqaJy/AjovIrG5BqeRkyRVaad0hxL4Cbogzxl2VFgCg=; b=ZcayHVrf0Al8yfcf2lWVDiYosAnraB/PknbEJMkJ3jC1tVC7cYvm6PVNa1vNM0BAtP jSy2NrrWJallrjR+Du/S89tnqQCvGsC1qfMCtpdN+Kop5YtLs1FoUX5IMEttNUpSPSUJ +sdS/mK++cYsPmjTTED+eHOqE8DOyFPEWXW8tR4b4lEJN7EshGhn4Nq+u8o10RfDdhiN K0OTjcn0Z5P0EBP+psjV7jNOsta+2tTODMf0JA7DHsoU6xy3A0BO6a71v+f4fWmobnkR W8KN2GWWBrb8LDKgvU8VIoNiAXguqEtY5L6FpzRc9hRBRgUYBz/iETPLs26XWrh8RmAO CrQg== 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=PqaJy/AjovIrG5BqeRkyRVaad0hxL4Cbogzxl2VFgCg=; b=aOLH0LjyitE2RjxE6Ft1ACx8w6Q+kGR6xwIyU6o4z9JlrMLBYOw+3nxZ3NhcVbA9bB uhWJALnwAaI65NcKYhbflQugVLJRZ+iEwfR6hVAyM99hx2XDtWdChW5T+e892AKT6GhY lMzpZjqkpETKhiD2QF29CV92S5ztix245qXMgGaV7q3zt98FxaoyWSNPlYTTXIVcNNFm YG+JQ7HTgtq2cQC39S7pSV0MCXVer5JfGVBJh8IKycTQ1a7dISpaRsNpmeB8tsF1geIT PwUPqfTSDqX0OtJD4vlkqdMY2SWsy+g0r1jRIfrsagsq2xmw+bgaXg3QCvtGm/d8KbZD FvuA== X-Gm-Message-State: AOAM531eDEnJx/X5tJKxdturBD7ZUDjWAfOyQr1LRa0AKuxCixSh4jzM 9B2VyOrpEL6ON/Jw7hUsJ1o= X-Google-Smtp-Source: ABdhPJyNEfMl2bi8IWQI/ULXvVG+geO4fnyWRNC3dwc5S07c+R0G91U7jymYfREohRvK+iSeGRugew== X-Received: by 2002:a17:90a:fb46:: with SMTP id iq6mr452961pjb.228.1623090153276; Mon, 07 Jun 2021 11:22:33 -0700 (PDT) Received: from localhost.localdomain ([103.200.106.115]) by smtp.googlemail.com with ESMTPSA id k1sm8687656pfa.30.2021.06.07.11.22.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Jun 2021 11:22:33 -0700 (PDT) From: Amey Narkhede To: Bjorn Helgaas Cc: alex.williamson@redhat.com, Raphael Norwitz , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, kw@linux.com, Shanker Donthineni , Sinan Kaya , Amey Narkhede Subject: [PATCH v6 3/8] PCI: Remove reset_fn field from pci_dev Date: Mon, 7 Jun 2021 23:51:32 +0530 Message-Id: <20210607182137.5794-4-ameynarkhede03@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210607182137.5794-1-ameynarkhede03@gmail.com> References: <20210607182137.5794-1-ameynarkhede03@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org reset_fn field is used to indicate whether the device supports any reset mechanism or not. Remove the use of reset_fn in favor of new reset_methods array which can be used to keep track of all supported reset mechanisms of a device and their ordering. The octeon driver is incorrectly using reset_fn field to detect if the device supports FLR or not. Use pcie_reset_flr() to probe whether it supports FLR or not. Reviewed-by: Alex Williamson Reviewed-by: Raphael Norwitz Co-developed-by: Alex Williamson Signed-off-by: Alex Williamson Signed-off-by: Amey Narkhede --- drivers/net/ethernet/cavium/liquidio/lio_vf_main.c | 2 +- drivers/pci/pci-sysfs.c | 2 +- drivers/pci/pci.c | 6 +++--- drivers/pci/probe.c | 1 - drivers/pci/quirks.c | 2 +- drivers/pci/remove.c | 1 - include/linux/pci.h | 1 - 7 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index 516f166ce..336d149ee 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -526,7 +526,7 @@ static void octeon_destroy_resources(struct octeon_device *oct) oct->irq_name_storage = NULL; } /* Soft reset the octeon device before exiting */ - if (oct->pci_dev->reset_fn) + if (!pcie_reset_flr(oct->pci_dev, 1)) octeon_pci_flr(oct); else cn23xx_vf_ask_pf_to_do_flr(oct); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index beb8d1f4f..316f70c3e 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -1367,7 +1367,7 @@ static umode_t pci_dev_reset_attr_is_visible(struct kobject *kobj, { struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); - if (!pdev->reset_fn) + if (!pci_reset_supported(pdev)) return 0; return a->mode; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 39a9ea8bb..2302aa421 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5232,7 +5232,7 @@ int pci_reset_function(struct pci_dev *dev) { int rc; - if (!dev->reset_fn) + if (!pci_reset_supported(dev)) return -ENOTTY; pci_dev_lock(dev); @@ -5268,7 +5268,7 @@ int pci_reset_function_locked(struct pci_dev *dev) { int rc; - if (!dev->reset_fn) + if (!pci_reset_supported(dev)) return -ENOTTY; pci_dev_save_and_disable(dev); @@ -5291,7 +5291,7 @@ int pci_try_reset_function(struct pci_dev *dev) { int rc; - if (!dev->reset_fn) + if (!pci_reset_supported(dev)) return -ENOTTY; if (!pci_dev_trylock(dev)) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 8cf532681..90fd4f61f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2405,7 +2405,6 @@ static void pci_init_capabilities(struct pci_dev *dev) pcie_report_downtraining(dev); pci_init_reset_methods(dev); - dev->reset_fn = pci_reset_supported(dev); } /* diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f977ba79a..e86cf4a3b 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -5589,7 +5589,7 @@ static void quirk_reset_lenovo_thinkpad_p50_nvgpu(struct pci_dev *pdev) if (pdev->subsystem_vendor != PCI_VENDOR_ID_LENOVO || pdev->subsystem_device != 0x222e || - !pdev->reset_fn) + !pci_reset_supported(pdev)) return; if (pci_enable_device_mem(pdev)) diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index dd12c2fcc..4c54c7505 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -19,7 +19,6 @@ static void pci_stop_dev(struct pci_dev *dev) pci_pme_active(dev, false); if (pci_dev_is_added(dev)) { - dev->reset_fn = 0; device_release_driver(&dev->dev); pci_proc_detach_device(dev); diff --git a/include/linux/pci.h b/include/linux/pci.h index 0955246f8..6e9bc4f9c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -429,7 +429,6 @@ struct pci_dev { unsigned int state_saved:1; unsigned int is_physfn:1; unsigned int is_virtfn:1; - unsigned int reset_fn:1; unsigned int is_hotplug_bridge:1; unsigned int shpc_managed:1; /* SHPC owned by shpchp */ unsigned int is_thunderbolt:1; /* Thunderbolt controller */ From patchwork Mon Jun 7 18:21:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ameynarkhede03 X-Patchwork-Id: 12304411 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B94D7C47094 for ; Mon, 7 Jun 2021 18:22:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 99B6361003 for ; Mon, 7 Jun 2021 18:22:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230291AbhFGSY3 (ORCPT ); Mon, 7 Jun 2021 14:24:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48830 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230287AbhFGSY2 (ORCPT ); Mon, 7 Jun 2021 14:24:28 -0400 Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 24B07C061789; Mon, 7 Jun 2021 11:22:37 -0700 (PDT) Received: by mail-pg1-x52f.google.com with SMTP id e20so2540002pgg.0; Mon, 07 Jun 2021 11:22:37 -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=2GwU7xVOO3aHdi2ZowTA3j4dg4Dx7tydRNZ94ujj3N0=; b=MIjew5yVD0th6cQq/FJP+aarKoKhSpZOm1Qah4059J/tpntR2hNOgmF7HxVrje22at l9ufVrRh9X8TmNc3bk5zFG8P7g9Acd5xnpTopJ0lk7w8Rdy8lYdIeEeuLxyQZvN3rPqK fzPm8DVCCWXffNDyIb0uORmHygVzBAamqkQmiTuRsdkBxj8bZZV7EBa+pAEjQqDETyJ6 1X4ypa4Ue3ijxLPi4iaMblnb3OLi+tucUboDVGzIgGMdkFKN7IMZE3d+pcMYzXFQl85j F48zPKv7rk3XkLak0Wv43oZ+Dv72CCVHT3DB3oc/1kJC6DBW/BJyI6W6vTs0OlYIF7fx lI8g== 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=2GwU7xVOO3aHdi2ZowTA3j4dg4Dx7tydRNZ94ujj3N0=; b=QkRQK4EhGfYlTgsWzP/p/tRUioe1rUhuLQ8ln/Wf6f2Hw4igs0bj4K6J8LmlgDas59 HdWK/5/3c+yCQER/rSAWOwt50mDbDb7Xa3ENmNOSfBTPY1PnVlATdWjKAGwOZlBDQriA 6bUr3v8Oj7QZPgQaRyM679K9893YVQhYBLs1IWGgxPr5gTosEFU3UYHttmlaAwfc2HeN fwTmH5k1Yoneq+eMcGNMXaV9RbRiMHHYA29nE6MRL4XP8m6su/U5eP1JskVN2QbvbAo9 /gMjE4lq2MqeSRG+oY8MJBRDRoNmL2sOAKbHM1qa7VFuwbGaWvoyAHEceJ9Gn+YPLOwt w7pQ== X-Gm-Message-State: AOAM530MRk3rmwIjxCd6636/aSYDwvm8hNmk2ZS8RpYpatabbuE2aqfN XcLiDUXYmr1HoixROoAhyNQVcEIyBvfugQ== X-Google-Smtp-Source: ABdhPJxC5P7m1JL/YO3vsYyXTRhcXG5b+o58cWEj43c18k0KVk0MAfK1ZE8CZscsvaTxj2z2VCpfhw== X-Received: by 2002:a63:404:: with SMTP id 4mr9761593pge.180.1623090156731; Mon, 07 Jun 2021 11:22:36 -0700 (PDT) Received: from localhost.localdomain ([103.200.106.115]) by smtp.googlemail.com with ESMTPSA id k1sm8687656pfa.30.2021.06.07.11.22.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Jun 2021 11:22:36 -0700 (PDT) From: Amey Narkhede To: Bjorn Helgaas Cc: alex.williamson@redhat.com, Raphael Norwitz , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, kw@linux.com, Shanker Donthineni , Sinan Kaya , Amey Narkhede Subject: [PATCH v6 4/8] PCI/sysfs: Allow userspace to query and set device reset mechanism Date: Mon, 7 Jun 2021 23:51:33 +0530 Message-Id: <20210607182137.5794-5-ameynarkhede03@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210607182137.5794-1-ameynarkhede03@gmail.com> References: <20210607182137.5794-1-ameynarkhede03@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Add reset_method sysfs attribute to enable user to query and set user preferred device reset methods and their ordering. Co-developed-by: Alex Williamson Signed-off-by: Alex Williamson Signed-off-by: Amey Narkhede --- Documentation/ABI/testing/sysfs-bus-pci | 16 ++++ drivers/pci/pci-sysfs.c | 118 ++++++++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index ef00fada2..cf6dbbb3c 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci @@ -121,6 +121,22 @@ Description: child buses, and re-discover devices removed earlier from this part of the device tree. +What: /sys/bus/pci/devices/.../reset_method +Date: March 2021 +Contact: Amey Narkhede +Description: + Some devices allow an individual function to be reset + without affecting other functions in the same slot. + For devices that have this support, a file named reset_method + will be present in sysfs. Reading this file will give names + of the device supported reset methods and their ordering. + Writing the name or comma separated list of names of any of + the device supported reset methods to this file will set the + reset methods and their ordering to be used when resetting + the device. Writing empty string to this file will disable + ability to reset the device and writing "default" will return + to the original value. + What: /sys/bus/pci/devices/.../reset Date: July 2009 Contact: Michael S. Tsirkin diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 316f70c3e..52def79aa 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -1334,6 +1334,123 @@ static const struct attribute_group pci_dev_rom_attr_group = { .is_bin_visible = pci_dev_rom_attr_is_visible, }; +static ssize_t reset_method_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct pci_dev *pdev = to_pci_dev(dev); + ssize_t len = 0; + int i, prio; + + for (prio = PCI_RESET_METHODS_NUM; prio; prio--) { + for (i = 0; i < PCI_RESET_METHODS_NUM; i++) { + if (prio == pdev->reset_methods[i]) { + len += sysfs_emit_at(buf, len, "%s%s", + len ? "," : "", + pci_reset_fn_methods[i].name); + break; + } + } + + if (i == PCI_RESET_METHODS_NUM) + break; + } + + if (len) + len += sysfs_emit_at(buf, len, "\n"); + + return len; +} + +static ssize_t reset_method_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u8 reset_methods[PCI_RESET_METHODS_NUM]; + struct pci_dev *pdev = to_pci_dev(dev); + u8 prio = PCI_RESET_METHODS_NUM; + char *name, *options; + int i; + + if (count >= (PAGE_SIZE - 1)) + return -EINVAL; + + options = kstrndup(buf, count, GFP_KERNEL); + if (!options) + return -ENOMEM; + + /* + * Initialize reset_method such that 0xff indicates + * supported but not currently enabled reset methods + * as we only use priority values which are within + * the range of PCI_RESET_FN_METHODS array size + */ + for (i = 0; i < PCI_RESET_METHODS_NUM; i++) + reset_methods[i] = pdev->reset_methods[i] ? 0xff : 0; + + if (sysfs_streq(options, "")) { + pci_warn(pdev, "All device reset methods disabled by user"); + goto set_reset_methods; + } + + if (sysfs_streq(options, "default")) { + for (i = 0; i < PCI_RESET_METHODS_NUM; i++) + reset_methods[i] = reset_methods[i] ? prio-- : 0; + goto set_reset_methods; + } + + while ((name = strsep(&options, ",")) != NULL) { + if (sysfs_streq(name, "")) + continue; + + name = strim(name); + + for (i = 0; i < PCI_RESET_METHODS_NUM; i++) { + if (reset_methods[i] && + sysfs_streq(name, pci_reset_fn_methods[i].name)) { + reset_methods[i] = prio--; + break; + } + } + + if (i == PCI_RESET_METHODS_NUM) { + kfree(options); + return -EINVAL; + } + } + + if (reset_methods[0] && + reset_methods[0] != PCI_RESET_METHODS_NUM) + pci_warn(pdev, "Device specific reset disabled/de-prioritized by user"); + +set_reset_methods: + kfree(options); + memcpy(pdev->reset_methods, reset_methods, sizeof(reset_methods)); + return count; +} +static DEVICE_ATTR_RW(reset_method); + +static struct attribute *pci_dev_reset_method_attrs[] = { + &dev_attr_reset_method.attr, + NULL, +}; + +static umode_t pci_dev_reset_method_attr_is_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); + + if (!pci_reset_supported(pdev)) + return 0; + + return a->mode; +} + +static const struct attribute_group pci_dev_reset_method_attr_group = { + .attrs = pci_dev_reset_method_attrs, + .is_visible = pci_dev_reset_method_attr_is_visible, +}; + static ssize_t reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -1491,6 +1608,7 @@ const struct attribute_group *pci_dev_groups[] = { &pci_dev_config_attr_group, &pci_dev_rom_attr_group, &pci_dev_reset_attr_group, + &pci_dev_reset_method_attr_group, &pci_dev_vpd_attr_group, #ifdef CONFIG_DMI &pci_dev_smbios_attr_group, From patchwork Mon Jun 7 18:21:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ameynarkhede03 X-Patchwork-Id: 12304423 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49EB0C47082 for ; Mon, 7 Jun 2021 18:23:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 33CA061003 for ; Mon, 7 Jun 2021 18:23:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230483AbhFGSZl (ORCPT ); Mon, 7 Jun 2021 14:25:41 -0400 Received: from mail-pf1-f177.google.com ([209.85.210.177]:39511 "EHLO mail-pf1-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230333AbhFGSZk (ORCPT ); Mon, 7 Jun 2021 14:25:40 -0400 Received: by mail-pf1-f177.google.com with SMTP id k15so13732434pfp.6; Mon, 07 Jun 2021 11:23:40 -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=fW5wfb8x41zglgHyAcUMAuIIBSAY+Ni+6lOFyDzIdFA=; b=o3G5oOU6//tIJmKmhES2tEXoxirzr608aHOc8pwpPnv8aQk+CdhyQcuc7joomfsHRT +PD6CMJS3QYCqh9nU1seiNikpZP/zHYeTf1au17XNqyzo3KxwNzttzJvnJGQmURZbEyc 6B8b4Z6K9SvsplGvLt6/DXoLmOgCA1xjkW1iYR/JaC1cKDa84xPGRs3Ddwy5AXllWd6B HzH3PYxry0KPMnpAN/BkX6/iank5e1G7OqqTg+yhkHaadhOUQpWcI4X2HafI6uGZTV06 Wzwzfl4PgvtZKP1LwQ449Nx9aLi74HRq0sDkIHKn0SQZj/i/Oe867Mdaa7YLLaL9Qjpv C7Kw== 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=fW5wfb8x41zglgHyAcUMAuIIBSAY+Ni+6lOFyDzIdFA=; b=sLYEYxEKAx4OT+2NE0FgDNjq53sVVBvMMk96HS8WhrAawHaR5Ms2EeVvPmBOOGgJDt daQdSmeV4pKyiUhLCug8R7XtVv4F9s9z9/A00OTxtXf7yKmnHGulK/f/ntTcJ84/jaTx r/jWHxQuDRDyEpGrSFprLIeOTq4+hRbeRkfcdN2aCLqSXCdof0K2h9q4FvyYiNuNYNJN WrdfU9vL/B0ng/SeTIfEl382eAKNIdv3iB+UFEsdgGlnNkZX94SQfyQParA0bO4XECTD KFystQFVXYTsZKy7jCitWhs/GwrrkBpbajHahgefYhN/QxuMq5PcGHpdHqy0hE2Ae7Oz +2kw== X-Gm-Message-State: AOAM533zEEp2mh4UpXfH3nfJ0efMt6er+2mjDBSBPqHoPuLLqvM9k0c/ 2wbNMmZJ8nxeBUxqKN2D6Kw= X-Google-Smtp-Source: ABdhPJxO6nuThz+aF2UXb1doXP7+lOWOJraO2hEpY3HD/g0jVsAVCm2yzSE/X1QuvzF+ieQN3iN1fQ== X-Received: by 2002:a62:30c2:0:b029:289:116c:ec81 with SMTP id w185-20020a6230c20000b0290289116cec81mr18598706pfw.42.1623090159879; Mon, 07 Jun 2021 11:22:39 -0700 (PDT) Received: from localhost.localdomain ([103.200.106.115]) by smtp.googlemail.com with ESMTPSA id k1sm8687656pfa.30.2021.06.07.11.22.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Jun 2021 11:22:39 -0700 (PDT) From: Amey Narkhede To: Bjorn Helgaas Cc: alex.williamson@redhat.com, Raphael Norwitz , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, kw@linux.com, Shanker Donthineni , Sinan Kaya Subject: [PATCH v6 5/8] PCI: Setup ACPI_COMPANION early Date: Mon, 7 Jun 2021 23:51:34 +0530 Message-Id: <20210607182137.5794-6-ameynarkhede03@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210607182137.5794-1-ameynarkhede03@gmail.com> References: <20210607182137.5794-1-ameynarkhede03@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Shanker Donthineni Currently, the ACPI_COMPANION is not available until device_add(). The software features which have dependency on ACPI fwnode properties and needs to be handled before device_add() will not work. One use case, software has to check the existence of _RST method to support ACPI based reset mechanism. This patch adds a new function pci_set_acpi_fwnode() for setting the ACPI_COMPANION, same code which is available in acpi_pci_bridge_d3(). Call pci_set_acpi_fwnode() from pci_scan_device() to fix the issue. Signed-off-by: Shanker Donthineni --- drivers/pci/pci-acpi.c | 12 ++++++++---- drivers/pci/pci.h | 2 ++ drivers/pci/probe.c | 2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 36bc23e21..eaddbf701 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -934,6 +934,13 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) static struct acpi_device *acpi_pci_find_companion(struct device *dev); +void pci_set_acpi_fwnode(struct pci_dev *dev) +{ + if (!ACPI_COMPANION(&dev->dev) && !pci_dev_is_added(dev)) + ACPI_COMPANION_SET(&dev->dev, + acpi_pci_find_companion(&dev->dev)); +} + static bool acpi_pci_bridge_d3(struct pci_dev *dev) { const struct fwnode_handle *fwnode; @@ -945,11 +952,8 @@ static bool acpi_pci_bridge_d3(struct pci_dev *dev) return false; /* Assume D3 support if the bridge is power-manageable by ACPI. */ + pci_set_acpi_fwnode(dev); adev = ACPI_COMPANION(&dev->dev); - if (!adev && !pci_dev_is_added(dev)) { - adev = acpi_pci_find_companion(&dev->dev); - ACPI_COMPANION_SET(&dev->dev, adev); - } if (adev && acpi_device_power_manageable(adev)) return true; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 13ec6bd6f..d22da6d3c 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -703,7 +703,9 @@ static inline int pci_aer_raw_clear_status(struct pci_dev *dev) { return -EINVAL #ifdef CONFIG_ACPI int pci_acpi_program_hp_params(struct pci_dev *dev); extern const struct attribute_group pci_dev_acpi_attr_group; +void pci_set_acpi_fwnode(struct pci_dev *dev); #else +static inline void pci_set_acpi_fwnode(struct pci_dev *dev) {} static inline int pci_acpi_program_hp_params(struct pci_dev *dev) { return -ENODEV; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 90fd4f61f..dfefa5ed0 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2359,6 +2359,8 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) return NULL; } + pci_set_acpi_fwnode(dev); + return dev; } From patchwork Mon Jun 7 18:21:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ameynarkhede03 X-Patchwork-Id: 12304417 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EA0C0C47094 for ; Mon, 7 Jun 2021 18:22:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CE9DA61107 for ; Mon, 7 Jun 2021 18:22:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230316AbhFGSYs (ORCPT ); Mon, 7 Jun 2021 14:24:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48858 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230239AbhFGSYr (ORCPT ); Mon, 7 Jun 2021 14:24:47 -0400 Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B8F74C061766; Mon, 7 Jun 2021 11:22:43 -0700 (PDT) Received: by mail-pl1-x631.google.com with SMTP id 69so9186175plc.5; Mon, 07 Jun 2021 11:22:43 -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=iNHrhq0IL96XZ0EI6v9hmr0ajyowuoqEGQEPG1rii/A=; b=L+XKyK9Xc/iP3xTzUjajXyy/0+DpVV+nzcEUa1HjSrX7McmLVt0we7X0ORMACcJgOu yeJCMAg+k19OdXBwPvh7c69u1/+evJzWDI8vfBioPgZrKBZhBE1AHH5gcySMN8BiOwJp GZla0MTWk3vIvF3Qj3esUtQMr+eIAa+Vq39XcP0AjZZMzb6evwVbL/PHPszcRMcpLhIP Abvr9n3ui7gNXbAneO/0XoAOrSneIZQ4CUeiraBWOIAhBRvBfCVps5Iu8GabKnAZ40r/ BlDXtH20og75bN11CmEWwq/KU74wMeXxD9MBMoe+V40fQyQwsfTWb3JBvIsptfc0Q2Kx zowg== 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=iNHrhq0IL96XZ0EI6v9hmr0ajyowuoqEGQEPG1rii/A=; b=fy/QtNOPmDuRvm3EzUCNZ9i3KZSbF0AyJ2fNaM2v457BUk1jDF5qLtC/gfGQBtYQb+ 5VokcncbDDdfNyu8z45+nC2ynT3CEjeeHZqWmLxEwWPbkMfDmqN/UG08W1PkFJEH94LN NBplcetQ2Z0HkuZCeGh40QOsezsj1mHVeepxRMQsA8q1D9rc7s3tUBaxCnwWIHCVZ2Y0 JrZbIHvIPN1IO6lMJCQH8Y1iAdIlhf26Vw1JscEEJeqlDKIntdQVaAYMtqBv7Onvj82L q/yaPTZcUv/05buPtEeG+FuCGDtpKACMwiZT7/onyW/nawz/RHVBd6S3xmwNyQ4i5xJD w9DQ== X-Gm-Message-State: AOAM531Zjpm3FugxCJI9NxR3gm9B/ZZch7OPx9bevC87RMOTklK6HNFy sPNDL+MluXDDCfg9aHcd/sc= X-Google-Smtp-Source: ABdhPJyTd0NkNIcVCMuvAgAaJVLy0DNbcZp4xeRSF9wybLHr5rTfUZdUo3r56WY3t6PsjWEfuu2HGw== X-Received: by 2002:a17:90a:9511:: with SMTP id t17mr22014125pjo.108.1623090163365; Mon, 07 Jun 2021 11:22:43 -0700 (PDT) Received: from localhost.localdomain ([103.200.106.115]) by smtp.googlemail.com with ESMTPSA id k1sm8687656pfa.30.2021.06.07.11.22.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Jun 2021 11:22:43 -0700 (PDT) From: Amey Narkhede To: Bjorn Helgaas Cc: alex.williamson@redhat.com, Raphael Norwitz , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, kw@linux.com, Shanker Donthineni , Sinan Kaya Subject: [PATCH v6 6/8] PCI: Add support for ACPI _RST reset method Date: Mon, 7 Jun 2021 23:51:35 +0530 Message-Id: <20210607182137.5794-7-ameynarkhede03@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210607182137.5794-1-ameynarkhede03@gmail.com> References: <20210607182137.5794-1-ameynarkhede03@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Shanker Donthineni The _RST is a standard method specified in the ACPI specification. It provides a function level reset when it is described in the acpi_device context associated with PCI-device. Implement a new reset function pci_dev_acpi_reset() for probing RST method and execute if it is defined in the firmware. The default priority of the ACPI reset is set to below device-specific and above hardware resets. Signed-off-by: Shanker Donthineni Suggested-by: Alex Williamson Reviewed-by: Sinan Kaya --- drivers/pci/pci-acpi.c | 23 +++++++++++++++++++++++ drivers/pci/pci.c | 1 + drivers/pci/pci.h | 6 ++++++ include/linux/pci.h | 2 +- 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index eaddbf701..40dd24cd3 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -941,6 +941,29 @@ void pci_set_acpi_fwnode(struct pci_dev *dev) acpi_pci_find_companion(&dev->dev)); } +/** + * pci_dev_acpi_reset - do a function level reset using _RST method + * @dev: device to reset + * @probe: check if _RST method is included in the acpi_device context. + */ +int pci_dev_acpi_reset(struct pci_dev *dev, int probe) +{ + acpi_handle handle = ACPI_HANDLE(&dev->dev); + + if (!handle || !acpi_has_method(handle, "_RST")) + return -ENOTTY; + + if (probe) + return 0; + + if (ACPI_FAILURE(acpi_evaluate_object(handle, "_RST", NULL, NULL))) { + pci_warn(dev, "ACPI _RST failed\n"); + return -EINVAL; + } + + return 0; +} + static bool acpi_pci_bridge_d3(struct pci_dev *dev) { const struct fwnode_handle *fwnode; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2302aa421..2e7efd7e7 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5121,6 +5121,7 @@ static void pci_dev_restore(struct pci_dev *dev) */ const struct pci_reset_fn_method pci_reset_fn_methods[] = { { &pci_dev_specific_reset, .name = "device_specific" }, + { &pci_dev_acpi_reset, .name = "acpi" }, { &pcie_reset_flr, .name = "flr" }, { &pci_af_flr, .name = "af_flr" }, { &pci_pm_reset, .name = "pm" }, diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d22da6d3c..e9cfb7cd6 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -704,7 +704,13 @@ static inline int pci_aer_raw_clear_status(struct pci_dev *dev) { return -EINVAL int pci_acpi_program_hp_params(struct pci_dev *dev); extern const struct attribute_group pci_dev_acpi_attr_group; void pci_set_acpi_fwnode(struct pci_dev *dev); +int pci_dev_acpi_reset(struct pci_dev *dev, int probe); #else +static inline int pci_dev_acpi_reset(struct pci_dev *dev, int probe) +{ + return -ENOTTY; +} + static inline void pci_set_acpi_fwnode(struct pci_dev *dev) {} static inline int pci_acpi_program_hp_params(struct pci_dev *dev) { diff --git a/include/linux/pci.h b/include/linux/pci.h index 6e9bc4f9c..a7f063da2 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -49,7 +49,7 @@ PCI_STATUS_SIG_TARGET_ABORT | \ PCI_STATUS_PARITY) -#define PCI_RESET_METHODS_NUM 5 +#define PCI_RESET_METHODS_NUM 6 /* * The PCI interface treats multi-function devices as independent From patchwork Mon Jun 7 18:21:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ameynarkhede03 X-Patchwork-Id: 12304427 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1C2C8C47094 for ; Mon, 7 Jun 2021 18:24:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F1C0B60FE4 for ; Mon, 7 Jun 2021 18:24:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230468AbhFGSZw (ORCPT ); Mon, 7 Jun 2021 14:25:52 -0400 Received: from mail-pg1-f171.google.com ([209.85.215.171]:42550 "EHLO mail-pg1-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230517AbhFGSZv (ORCPT ); Mon, 7 Jun 2021 14:25:51 -0400 Received: by mail-pg1-f171.google.com with SMTP id i34so8055694pgl.9; Mon, 07 Jun 2021 11:23:46 -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=IWfL/IMqwLqFbs476iJcEczTrUNwgxx26bfBJrumYEY=; b=t4niVb4NyxkyQjtsiCndAlVFKwNMPVVuC6HsFIwj3dBdzmpr423OuRwwn2qZr+O/t3 x4PYH0E5CW5CSU+FEXmWq7QZKJmQ03tSIROUrSJ/M+cjWlQx1NFqumi1rf3lwZKWGxGO 9PBaJtSu0u5eJP6EVO9grTVfeOLaMf5zF3ufn7ZRKxqASBAu9Tusk7Rb8f685CRj20Jc VG3qeyPnXuepqRr26Hu7jLK2nq4J2BuwQCztMFlGirVCScY9BDezVWSmTurrtIIo0pCT B19y8DzHNpYZ+JcO0/bP0FPIE0tqULvyay/8sMYOmMAw7ZnK0iqDw4QgGzWUibTC27Sg yu8g== 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=IWfL/IMqwLqFbs476iJcEczTrUNwgxx26bfBJrumYEY=; b=ejZGAlVyffLlklTpn/942IQG6u170FObS1lDN12ligyuYiuhesYfPSNUzxAyeuDb0a /B6jsc8lGg8FN1R9JuSEkszQANLuMMTStby67p3NrJjUjNqB0G5CcW04tk1Rw8fsqQ5q LGLjdZg+2IzYytfFlB0h2SRxMIYuSQ0VGga4aOh5wzbJMoIMMs3UIY2I/4Rn0TIvNNZA GBVnVHxp8H4wJvxHhEhNiwALvLwNh80jja5ktQbalw6QYoFqhyv+9ZXbuHy/VczrhG33 6PWBKqdIALDYBpBheEKx+w2R30JUNMV6jfi5GlSvQguxtsvqKpgJDVwTQSDJYKbDIGUb glhA== X-Gm-Message-State: AOAM532Wk25G0QND/ZMEILHWYfetHvGYw/Im93WK9ZDYu5DLCxd5t8gd JP6aYFggpU+jF6xNiVwTXQU= X-Google-Smtp-Source: ABdhPJy+jgkF8ojBGMdLKOcnpcqCKTBTJcOe0/s5bziiC8emszZ93nSxgbMja9k9wjTTnzO44vwcdQ== X-Received: by 2002:aa7:97b8:0:b029:2e9:df45:f83f with SMTP id d24-20020aa797b80000b02902e9df45f83fmr18817831pfq.10.1623090166822; Mon, 07 Jun 2021 11:22:46 -0700 (PDT) Received: from localhost.localdomain ([103.200.106.115]) by smtp.googlemail.com with ESMTPSA id k1sm8687656pfa.30.2021.06.07.11.22.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Jun 2021 11:22:46 -0700 (PDT) From: Amey Narkhede To: Bjorn Helgaas Cc: alex.williamson@redhat.com, Raphael Norwitz , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, kw@linux.com, Shanker Donthineni , Sinan Kaya Subject: [PATCH v6 7/8] PCI: Enable NO_BUS_RESET quirk for Nvidia GPUs Date: Mon, 7 Jun 2021 23:51:36 +0530 Message-Id: <20210607182137.5794-8-ameynarkhede03@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210607182137.5794-1-ameynarkhede03@gmail.com> References: <20210607182137.5794-1-ameynarkhede03@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Shanker Donthineni On select platforms, some Nvidia GPU devices do not work with SBR. Triggering SBR would leave the device inoperable for the current system boot. It requires a system hard-reboot to get the GPU device back to normal operating condition post-SBR. For the affected devices, enable NO_BUS_RESET quirk to fix the issue. This issue will be fixed in the next generation of hardware. Signed-off-by: Shanker Donthineni Reviewed-by: Sinan Kaya --- drivers/pci/quirks.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e86cf4a3b..45a8c3caa 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3546,6 +3546,18 @@ static void quirk_no_bus_reset(struct pci_dev *dev) dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET; } +/* + * Some Nvidia GPU devices do not work with bus reset, SBR needs to be + * prevented for those affected devices. + */ +static void quirk_nvidia_no_bus_reset(struct pci_dev *dev) +{ + if ((dev->device & 0xffc0) == 0x2340) + quirk_no_bus_reset(dev); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, + quirk_nvidia_no_bus_reset); + /* * Some Atheros AR9xxx and QCA988x chips do not behave after a bus reset. * The device will throw a Link Down error on AER-capable systems and From patchwork Mon Jun 7 18:21:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: ameynarkhede03 X-Patchwork-Id: 12304425 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26256C47082 for ; Mon, 7 Jun 2021 18:23:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0A7AC61139 for ; Mon, 7 Jun 2021 18:23:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231268AbhFGSZm (ORCPT ); Mon, 7 Jun 2021 14:25:42 -0400 Received: from mail-pj1-f47.google.com ([209.85.216.47]:50969 "EHLO mail-pj1-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231258AbhFGSZm (ORCPT ); Mon, 7 Jun 2021 14:25:42 -0400 Received: by mail-pj1-f47.google.com with SMTP id g4so914751pjk.0; Mon, 07 Jun 2021 11:23:50 -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=VnM0nNSMhXc77uUkQzyB3KIP0EQuYP1wjvaS4EK4kV4=; b=oVvqgjagbKzCi2D7y1IpG5I4Lx0Quz5PeJMG9dLBue9TuCQ2i2NwUI5DSGTZZypx3a gCYxPcPI2KJ5pP5UIjvlQTseWhb/5tooqRdSz7c5TSp+ewrphWpRlV+14643+NNNZZ+O thvAjJz1a/nyKbzuRZyQkuxznCaA+1bSTMo/ghU/GcLXoMplMKub7j4vzXl3QEJY8EbA ax2THquao6XwVtcIWCXWkkuGBWl71AcE/QZMQYQqYA8Ti+W/fN0k+PyxqICscA6X10hH 2diigYK93P2ce7FnYEh9Xi6gWvrwso/UIlwMHp9jrfo3cU4YytevsSzoqS6ljwFmfQ4/ j/vg== 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=VnM0nNSMhXc77uUkQzyB3KIP0EQuYP1wjvaS4EK4kV4=; b=bQ1G4m/pdAa69QYY1OWicCyy7V9n0/3Hha/xLuDm6gg5MjUAiPqmN+nhn/3wceYCYq W8F29VJFtKdW57vfK54QKm3+gWaHAFGN0uwtY3NFnL+lypNJShYcWEyWDuk7G5jSrq94 0Ssjvf3fjiPH3JQRj9J5Y0cdJ1gjXvn0UHFV6wjv4pWy5aDNKX7MydtP42kJRCoXm714 P7rw60t8IWR/VHqcxz2WtL9PVbw9qYG+oOYjgVDZhDC4mwIUUO7n8QLxbOa2B26jIot9 0vS9azzVdpljQod4HloI2GPDzfCTN7LiLBc1JUCnAWxKyz7yte5if6i+jjWsiLepaC76 pWfA== X-Gm-Message-State: AOAM531JAK2BRfJnX8/XSfE56V/ZEzRBBbcdBrAbOS+4Yk36k/VATRxF dJBXVWuTDx2jdXvCzwcdAVk= X-Google-Smtp-Source: ABdhPJwLREyLYzUFano8sSmin3NBhVZRbdkXchLHNV01zmZpYGheH3q8X8QGhcvoXp16LKV1Xyr2Mg== X-Received: by 2002:a17:90b:4b49:: with SMTP id mi9mr21303820pjb.187.1623090170394; Mon, 07 Jun 2021 11:22:50 -0700 (PDT) Received: from localhost.localdomain ([103.200.106.115]) by smtp.googlemail.com with ESMTPSA id k1sm8687656pfa.30.2021.06.07.11.22.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Jun 2021 11:22:50 -0700 (PDT) From: Amey Narkhede To: Bjorn Helgaas Cc: alex.williamson@redhat.com, Raphael Norwitz , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, kw@linux.com, Shanker Donthineni , Sinan Kaya , Amey Narkhede Subject: [PATCH v6 8/8] PCI: Change the type of probe argument in reset functions Date: Mon, 7 Jun 2021 23:51:37 +0530 Message-Id: <20210607182137.5794-9-ameynarkhede03@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210607182137.5794-1-ameynarkhede03@gmail.com> References: <20210607182137.5794-1-ameynarkhede03@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Introduce a new enum pci_reset_mode_t to make the context of probe argument in reset functions clear and the code easier to read. Change the type of probe argument in functions which implement reset methods from int to pci_reset_mode_t to make the intent clear. Add a new line in return statement of pci_reset_bus_function(). Suggested-by: Alex Williamson Suggested-by: Krzysztof WilczyƄski Signed-off-by: Amey Narkhede Reported-by: kernel test robot --- drivers/crypto/cavium/nitrox/nitrox_main.c | 2 +- .../ethernet/cavium/liquidio/lio_vf_main.c | 2 +- drivers/pci/hotplug/pciehp.h | 2 +- drivers/pci/hotplug/pciehp_hpc.c | 4 +- drivers/pci/pci-acpi.c | 10 ++- drivers/pci/pci.c | 85 ++++++++++++------- drivers/pci/pci.h | 10 +-- drivers/pci/pcie/aer.c | 2 +- drivers/pci/quirks.c | 37 ++++---- include/linux/pci.h | 8 +- include/linux/pci_hotplug.h | 2 +- 11 files changed, 100 insertions(+), 64 deletions(-) -- 2.31.1 diff --git a/drivers/crypto/cavium/nitrox/nitrox_main.c b/drivers/crypto/cavium/nitrox/nitrox_main.c index 15d6c8452..f97fa8e99 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_main.c +++ b/drivers/crypto/cavium/nitrox/nitrox_main.c @@ -306,7 +306,7 @@ static int nitrox_device_flr(struct pci_dev *pdev) return -ENOMEM; } - pcie_reset_flr(pdev, 0); + pcie_reset_flr(pdev, PCI_RESET_DO_RESET); pci_restore_state(pdev); diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index 336d149ee..6e666be69 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -526,7 +526,7 @@ static void octeon_destroy_resources(struct octeon_device *oct) oct->irq_name_storage = NULL; } /* Soft reset the octeon device before exiting */ - if (!pcie_reset_flr(oct->pci_dev, 1)) + if (!pcie_reset_flr(oct->pci_dev, PCI_RESET_PROBE)) octeon_pci_flr(oct); else cn23xx_vf_ask_pf_to_do_flr(oct); diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 4fd200d8b..87da03adc 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -181,7 +181,7 @@ void pciehp_release_ctrl(struct controller *ctrl); int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot); int pciehp_sysfs_disable_slot(struct hotplug_slot *hotplug_slot); -int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, int probe); +int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, pci_reset_mode_t mode); int pciehp_get_attention_status(struct hotplug_slot *hotplug_slot, u8 *status); int pciehp_set_raw_indicator_status(struct hotplug_slot *h_slot, u8 status); int pciehp_get_raw_indicator_status(struct hotplug_slot *h_slot, u8 *status); diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index fb3840e22..24b3c8787 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -834,14 +834,14 @@ void pcie_disable_interrupt(struct controller *ctrl) * momentarily, if we see that they could interfere. Also, clear any spurious * events after. */ -int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, int probe) +int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, pci_reset_mode_t mode) { struct controller *ctrl = to_ctrl(hotplug_slot); struct pci_dev *pdev = ctrl_dev(ctrl); u16 stat_mask = 0, ctrl_mask = 0; int rc; - if (probe) + if (mode == PCI_RESET_PROBE) return 0; down_write(&ctrl->reset_lock); diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 40dd24cd3..9de334457 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -944,16 +944,20 @@ void pci_set_acpi_fwnode(struct pci_dev *dev) /** * pci_dev_acpi_reset - do a function level reset using _RST method * @dev: device to reset - * @probe: check if _RST method is included in the acpi_device context. + * @probe: If PCI_RESET_PROBE, check whether _RST method is included + * in the acpi_device context. */ -int pci_dev_acpi_reset(struct pci_dev *dev, int probe) +int pci_dev_acpi_reset(struct pci_dev *dev, pci_reset_mode_t mode) { acpi_handle handle = ACPI_HANDLE(&dev->dev); + if (mode >= PCI_RESET_MODE_MAX) + return -EINVAL; + if (!handle || !acpi_has_method(handle, "_RST")) return -ENOTTY; - if (probe) + if (mode == PCI_RESET_PROBE) return 0; if (ACPI_FAILURE(acpi_evaluate_object(handle, "_RST", NULL, NULL))) { diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2e7efd7e7..e28611d7c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4650,14 +4650,17 @@ EXPORT_SYMBOL_GPL(pcie_flr); /** * pcie_reset_flr - initiate a PCIe function level reset * @dev: device to reset - * @probe: If set, only check if the device can be reset this way. + * @mode: If PCI_RESET_PROBE, only check if the device can be reset this way. * * Initiate a function level reset on @dev. */ -int pcie_reset_flr(struct pci_dev *dev, int probe) +int pcie_reset_flr(struct pci_dev *dev, pci_reset_mode_t mode) { u32 cap; + if (mode >= PCI_RESET_MODE_MAX) + return -EINVAL; + if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET) return -ENOTTY; @@ -4665,18 +4668,21 @@ int pcie_reset_flr(struct pci_dev *dev, int probe) if (!(cap & PCI_EXP_DEVCAP_FLR)) return -ENOTTY; - if (probe) + if (mode == PCI_RESET_PROBE) return 0; return pcie_flr(dev); } EXPORT_SYMBOL_GPL(pcie_reset_flr); -static int pci_af_flr(struct pci_dev *dev, int probe) +static int pci_af_flr(struct pci_dev *dev, pci_reset_mode_t mode) { int pos; u8 cap; + if (mode >= PCI_RESET_MODE_MAX) + return -EINVAL; + pos = pci_find_capability(dev, PCI_CAP_ID_AF); if (!pos) return -ENOTTY; @@ -4688,7 +4694,7 @@ static int pci_af_flr(struct pci_dev *dev, int probe) if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR)) return -ENOTTY; - if (probe) + if (mode == PCI_RESET_PROBE) return 0; /* @@ -4719,7 +4725,7 @@ static int pci_af_flr(struct pci_dev *dev, int probe) /** * pci_pm_reset - Put device into PCI_D3 and back into PCI_D0. * @dev: Device to reset. - * @probe: If set, only check if the device can be reset this way. + * @mode: If PCI_RESET_PROBE, only check if the device can be reset this way. * * If @dev supports native PCI PM and its PCI_PM_CTRL_NO_SOFT_RESET flag is * unset, it will be reinitialized internally when going from PCI_D3hot to @@ -4731,10 +4737,13 @@ static int pci_af_flr(struct pci_dev *dev, int probe) * by default (i.e. unless the @dev's d3hot_delay field has a different value). * Moreover, only devices in D0 can be reset by this function. */ -static int pci_pm_reset(struct pci_dev *dev, int probe) +static int pci_pm_reset(struct pci_dev *dev, pci_reset_mode_t mode) { u16 csr; + if (mode >= PCI_RESET_MODE_MAX) + return -EINVAL; + if (!dev->pm_cap || dev->dev_flags & PCI_DEV_FLAGS_NO_PM_RESET) return -ENOTTY; @@ -4742,7 +4751,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) if (csr & PCI_PM_CTRL_NO_SOFT_RESET) return -ENOTTY; - if (probe) + if (mode == PCI_RESET_PROBE) return 0; if (dev->current_state != PCI_D0) @@ -4991,10 +5000,13 @@ int pci_bridge_secondary_bus_reset(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset); -static int pci_parent_bus_reset(struct pci_dev *dev, int probe) +static int pci_parent_bus_reset(struct pci_dev *dev, pci_reset_mode_t mode) { struct pci_dev *pdev; + if (mode >= PCI_RESET_MODE_MAX) + return -EINVAL; + if (pci_is_root_bus(dev->bus) || dev->subordinate || !dev->bus->self || dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) return -ENOTTY; @@ -5003,44 +5015,47 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe) if (pdev != dev) return -ENOTTY; - if (probe) + if (mode == PCI_RESET_PROBE) return 0; return pci_bridge_secondary_bus_reset(dev->bus->self); } -static int pci_reset_hotplug_slot(struct hotplug_slot *hotplug, int probe) +static int pci_reset_hotplug_slot(struct hotplug_slot *hotplug, pci_reset_mode_t mode) { int rc = -ENOTTY; + if (mode >= PCI_RESET_MODE_MAX) + return -EINVAL; + if (!hotplug || !try_module_get(hotplug->owner)) return rc; if (hotplug->ops->reset_slot) - rc = hotplug->ops->reset_slot(hotplug, probe); + rc = hotplug->ops->reset_slot(hotplug, mode); module_put(hotplug->owner); return rc; } -static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe) +static int pci_dev_reset_slot_function(struct pci_dev *dev, pci_reset_mode_t mode) { if (dev->multifunction || dev->subordinate || !dev->slot || dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) return -ENOTTY; - return pci_reset_hotplug_slot(dev->slot->hotplug, probe); + return pci_reset_hotplug_slot(dev->slot->hotplug, mode); } -static int pci_reset_bus_function(struct pci_dev *dev, int probe) +static int pci_reset_bus_function(struct pci_dev *dev, pci_reset_mode_t mode) { int rc; - rc = pci_dev_reset_slot_function(dev, probe); + rc = pci_dev_reset_slot_function(dev, mode); if (rc != -ENOTTY) return rc; - return pci_parent_bus_reset(dev, probe); + return pci_parent_bus_reset(dev, mode); } static void pci_dev_lock(struct pci_dev *dev) @@ -5168,7 +5183,7 @@ int __pci_reset_function_locked(struct pci_dev *dev) * finished: this indicates that further reset * mechanisms might be broken on the device. */ - rc = pci_reset_fn_methods[i].reset_fn(dev, 0); + rc = pci_reset_fn_methods[i].reset_fn(dev, PCI_RESET_DO_RESET); if (rc != -ENOTTY) return rc; break; @@ -5204,7 +5219,7 @@ void pci_init_reset_methods(struct pci_dev *dev) might_sleep(); for (i = 0; i < PCI_RESET_METHODS_NUM; i++) { - rc = pci_reset_fn_methods[i].reset_fn(dev, 1); + rc = pci_reset_fn_methods[i].reset_fn(dev, PCI_RESET_PROBE); if (!rc) reset_methods[i] = prio--; else if (rc != -ENOTTY) @@ -5520,21 +5535,24 @@ static void pci_slot_restore_locked(struct pci_slot *slot) } } -static int pci_slot_reset(struct pci_slot *slot, int probe) +static int pci_slot_reset(struct pci_slot *slot, pci_reset_mode_t mode) { int rc; + if (mode >= PCI_RESET_MODE_MAX) + return -EINVAL; + if (!slot || !pci_slot_resetable(slot)) return -ENOTTY; - if (!probe) + if (mode != PCI_RESET_PROBE) pci_slot_lock(slot); might_sleep(); - rc = pci_reset_hotplug_slot(slot->hotplug, probe); + rc = pci_reset_hotplug_slot(slot->hotplug, mode); - if (!probe) + if (mode != PCI_RESET_PROBE) pci_slot_unlock(slot); return rc; @@ -5548,7 +5566,7 @@ static int pci_slot_reset(struct pci_slot *slot, int probe) */ int pci_probe_reset_slot(struct pci_slot *slot) { - return pci_slot_reset(slot, 1); + return pci_slot_reset(slot, PCI_RESET_PROBE); } EXPORT_SYMBOL_GPL(pci_probe_reset_slot); @@ -5571,14 +5589,14 @@ static int __pci_reset_slot(struct pci_slot *slot) { int rc; - rc = pci_slot_reset(slot, 1); + rc = pci_slot_reset(slot, PCI_RESET_PROBE); if (rc) return rc; if (pci_slot_trylock(slot)) { pci_slot_save_and_disable_locked(slot); might_sleep(); - rc = pci_reset_hotplug_slot(slot->hotplug, 0); + rc = pci_reset_hotplug_slot(slot->hotplug, PCI_RESET_DO_RESET); pci_slot_restore_locked(slot); pci_slot_unlock(slot); } else @@ -5587,14 +5605,17 @@ static int __pci_reset_slot(struct pci_slot *slot) return rc; } -static int pci_bus_reset(struct pci_bus *bus, int probe) +static int pci_bus_reset(struct pci_bus *bus, pci_reset_mode_t mode) { int ret; + if (mode >= PCI_RESET_MODE_MAX) + return -EINVAL; + if (!bus->self || !pci_bus_resetable(bus)) return -ENOTTY; - if (probe) + if (mode == PCI_RESET_PROBE) return 0; pci_bus_lock(bus); @@ -5633,14 +5654,14 @@ int pci_bus_error_reset(struct pci_dev *bridge) goto bus_reset; list_for_each_entry(slot, &bus->slots, list) - if (pci_slot_reset(slot, 0)) + if (pci_slot_reset(slot, PCI_RESET_DO_RESET)) goto bus_reset; mutex_unlock(&pci_slot_mutex); return 0; bus_reset: mutex_unlock(&pci_slot_mutex); - return pci_bus_reset(bridge->subordinate, 0); + return pci_bus_reset(bridge->subordinate, PCI_RESET_DO_RESET); } /** @@ -5651,7 +5672,7 @@ int pci_bus_error_reset(struct pci_dev *bridge) */ int pci_probe_reset_bus(struct pci_bus *bus) { - return pci_bus_reset(bus, 1); + return pci_bus_reset(bus, PCI_RESET_PROBE); } EXPORT_SYMBOL_GPL(pci_probe_reset_bus); @@ -5665,7 +5686,7 @@ static int __pci_reset_bus(struct pci_bus *bus) { int rc; - rc = pci_bus_reset(bus, 1); + rc = pci_bus_reset(bus, PCI_RESET_PROBE); if (rc) return rc; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index e9cfb7cd6..21ac02a9d 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -603,19 +603,19 @@ static inline int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) struct pci_dev_reset_methods { u16 vendor; u16 device; - int (*reset)(struct pci_dev *dev, int probe); + int (*reset)(struct pci_dev *dev, pci_reset_mode_t mode); }; struct pci_reset_fn_method { - int (*reset_fn)(struct pci_dev *pdev, int probe); + int (*reset_fn)(struct pci_dev *pdev, pci_reset_mode_t mode); char *name; }; extern const struct pci_reset_fn_method pci_reset_fn_methods[]; #ifdef CONFIG_PCI_QUIRKS -int pci_dev_specific_reset(struct pci_dev *dev, int probe); +int pci_dev_specific_reset(struct pci_dev *dev, pci_reset_mode_t mode); #else -static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) +static inline int pci_dev_specific_reset(struct pci_dev *dev, pci_reset_mode_t mode) { return -ENOTTY; } @@ -704,7 +704,7 @@ static inline int pci_aer_raw_clear_status(struct pci_dev *dev) { return -EINVAL int pci_acpi_program_hp_params(struct pci_dev *dev); extern const struct attribute_group pci_dev_acpi_attr_group; void pci_set_acpi_fwnode(struct pci_dev *dev); -int pci_dev_acpi_reset(struct pci_dev *dev, int probe); +int pci_dev_acpi_reset(struct pci_dev *dev, pci_reset_mode_t mode); #else static inline int pci_dev_acpi_reset(struct pci_dev *dev, int probe) { diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index 98077595a..cfa7a1775 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -1405,7 +1405,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) } if (type == PCI_EXP_TYPE_RC_EC || type == PCI_EXP_TYPE_RC_END) { - rc = pcie_reset_flr(dev, 0); + rc = pcie_reset_flr(dev, PCI_RESET_DO_RESET); if (!rc) pci_info(dev, "has been reset\n"); else diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 45a8c3caa..60fd101ac 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3681,7 +3681,7 @@ DECLARE_PCI_FIXUP_SUSPEND_LATE(PCI_VENDOR_ID_INTEL, * reset a single function if other methods (e.g. FLR, PM D0->D3) are * not available. */ -static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) +static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, pci_reset_mode_t mode) { /* * http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf @@ -3691,7 +3691,7 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) * Thus we must call pcie_flr() directly without first checking if it is * supported. */ - if (!probe) + if (mode == PCI_RESET_DO_RESET) pcie_flr(dev); return 0; } @@ -3703,13 +3703,13 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) #define NSDE_PWR_STATE 0xd0100 #define IGD_OPERATION_TIMEOUT 10000 /* set timeout 10 seconds */ -static int reset_ivb_igd(struct pci_dev *dev, int probe) +static int reset_ivb_igd(struct pci_dev *dev, pci_reset_mode_t mode) { void __iomem *mmio_base; unsigned long timeout; u32 val; - if (probe) + if (mode == PCI_RESET_PROBE) return 0; mmio_base = pci_iomap(dev, 0, 0); @@ -3746,7 +3746,7 @@ static int reset_ivb_igd(struct pci_dev *dev, int probe) } /* Device-specific reset method for Chelsio T4-based adapters */ -static int reset_chelsio_generic_dev(struct pci_dev *dev, int probe) +static int reset_chelsio_generic_dev(struct pci_dev *dev, pci_reset_mode_t mode) { u16 old_command; u16 msix_flags; @@ -3762,7 +3762,7 @@ static int reset_chelsio_generic_dev(struct pci_dev *dev, int probe) * If this is the "probe" phase, return 0 indicating that we can * reset this device. */ - if (probe) + if (mode == PCI_RESET_PROBE) return 0; /* @@ -3824,17 +3824,17 @@ static int reset_chelsio_generic_dev(struct pci_dev *dev, int probe) * Chapter 3: NVMe control registers * Chapter 7.3: Reset behavior */ -static int nvme_disable_and_flr(struct pci_dev *dev, int probe) +static int nvme_disable_and_flr(struct pci_dev *dev, pci_reset_mode_t mode) { void __iomem *bar; u16 cmd; u32 cfg; if (dev->class != PCI_CLASS_STORAGE_EXPRESS || - pcie_reset_flr(dev, 1) || !pci_resource_start(dev, 0)) + pcie_reset_flr(dev, PCI_RESET_PROBE) || !pci_resource_start(dev, 0)) return -ENOTTY; - if (probe) + if (mode == PCI_RESET_PROBE) return 0; bar = pci_iomap(dev, 0, NVME_REG_CC + sizeof(cfg)); @@ -3898,11 +3898,13 @@ static int nvme_disable_and_flr(struct pci_dev *dev, int probe) * device too soon after FLR. A 250ms delay after FLR has heuristically * proven to produce reliably working results for device assignment cases. */ -static int delay_250ms_after_flr(struct pci_dev *dev, int probe) +static int delay_250ms_after_flr(struct pci_dev *dev, pci_reset_mode_t mode) { - int ret = pcie_reset_flr(dev, probe); + int ret; + + ret = pcie_reset_flr(dev, mode); - if (probe) + if (ret || mode == PCI_RESET_PROBE) return ret; msleep(250); @@ -3918,13 +3920,13 @@ static int delay_250ms_after_flr(struct pci_dev *dev, int probe) #define HINIC_OPERATION_TIMEOUT 15000 /* 15 seconds */ /* Device-specific reset method for Huawei Intelligent NIC virtual functions */ -static int reset_hinic_vf_dev(struct pci_dev *pdev, int probe) +static int reset_hinic_vf_dev(struct pci_dev *pdev, pci_reset_mode_t mode) { unsigned long timeout; void __iomem *bar; u32 val; - if (probe) + if (mode == PCI_RESET_PROBE) return 0; bar = pci_iomap(pdev, 0, 0); @@ -3995,16 +3997,19 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { * because when a host assigns a device to a guest VM, the host may need * to reset the device but probably doesn't have a driver for it. */ -int pci_dev_specific_reset(struct pci_dev *dev, int probe) +int pci_dev_specific_reset(struct pci_dev *dev, pci_reset_mode_t mode) { const struct pci_dev_reset_methods *i; + if (mode >= PCI_RESET_MODE_MAX) + return -EINVAL; + for (i = pci_dev_reset_methods; i->reset; i++) { if ((i->vendor == dev->vendor || i->vendor == (u16)PCI_ANY_ID) && (i->device == dev->device || i->device == (u16)PCI_ANY_ID)) - return i->reset(dev, probe); + return i->reset(dev, mode); } return -ENOTTY; diff --git a/include/linux/pci.h b/include/linux/pci.h index a7f063da2..c46df52e6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -51,6 +51,12 @@ #define PCI_RESET_METHODS_NUM 6 +typedef enum pci_reset_mode { + PCI_RESET_DO_RESET, + PCI_RESET_PROBE, + PCI_RESET_MODE_MAX, +} pci_reset_mode_t; + /* * The PCI interface treats multi-function devices as independent * devices. The slot/function address of each device is encoded @@ -1230,7 +1236,7 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev, enum pci_bus_speed *speed, enum pcie_link_width *width); void pcie_print_link_status(struct pci_dev *dev); -int pcie_reset_flr(struct pci_dev *dev, int probe); +int pcie_reset_flr(struct pci_dev *dev, pci_reset_mode_t mode); int pcie_flr(struct pci_dev *dev); bool pci_reset_supported(struct pci_dev *dev); int __pci_reset_function_locked(struct pci_dev *dev); diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index b482e42d7..9e8da46e7 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -44,7 +44,7 @@ struct hotplug_slot_ops { int (*get_attention_status) (struct hotplug_slot *slot, u8 *value); int (*get_latch_status) (struct hotplug_slot *slot, u8 *value); int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value); - int (*reset_slot) (struct hotplug_slot *slot, int probe); + int (*reset_slot) (struct hotplug_slot *slot, pci_reset_mode_t mode); }; /**