From patchwork Fri Feb 3 17:55:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 9554789 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1A669602B7 for ; Fri, 3 Feb 2017 17:47:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0886D283F7 for ; Fri, 3 Feb 2017 17:47:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F162C28425; Fri, 3 Feb 2017 17:47:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A6116283F7 for ; Fri, 3 Feb 2017 17:47:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751457AbdBCRrR (ORCPT ); Fri, 3 Feb 2017 12:47:17 -0500 Received: from mga01.intel.com ([192.55.52.88]:40019 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751637AbdBCRrP (ORCPT ); Fri, 3 Feb 2017 12:47:15 -0500 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP; 03 Feb 2017 09:47:10 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,329,1477983600"; d="scan'208";a="1121750266" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.96]) by fmsmga002.fm.intel.com with ESMTP; 03 Feb 2017 09:47:10 -0800 From: Keith Busch To: linux-pci@vger.kernel.org, Bjorn Helgaas Cc: Greg Kroah-Hartman , Lukas Wunner , Wei Zhang , Austin Bolen , Christoph Hellwig , Keith Busch Subject: [PATCHv5 3/5] pci: No config access for disconnected devices Date: Fri, 3 Feb 2017 12:55:53 -0500 Message-Id: <1486144555-5526-4-git-send-email-keith.busch@intel.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1486144555-5526-1-git-send-email-keith.busch@intel.com> References: <1486144555-5526-1-git-send-email-keith.busch@intel.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If we've detected the PCI device is disconnected, there is no need to attempt to access its config space since we know the operation will fail. This patch has all the config reads and writes return -ENODEV error immediately when in such a state. If a config read is sent to a disconnected device, the value will be set to all 1's. This is the same as what hardware is expected to return when accessing a removed device, but software can do this faster without relying on hardware. Signed-off-by: Keith Busch Reviewed-by: Christoph Hellwig --- drivers/pci/access.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index d37b2ed..d63e9dd 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -892,12 +892,20 @@ EXPORT_SYMBOL(pcie_capability_clear_and_set_dword); int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val) { + if (pci_dev_is_disconnected(dev)) { + *val = ~0; + return -ENODEV; + } return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val); } EXPORT_SYMBOL(pci_read_config_byte); int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val) { + if (pci_dev_is_disconnected(dev)) { + *val = ~0; + return -ENODEV; + } return pci_bus_read_config_word(dev->bus, dev->devfn, where, val); } EXPORT_SYMBOL(pci_read_config_word); @@ -905,18 +913,26 @@ EXPORT_SYMBOL(pci_read_config_word); int pci_read_config_dword(const struct pci_dev *dev, int where, u32 *val) { + if (pci_dev_is_disconnected(dev)) { + *val = ~0; + return -ENODEV; + } return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val); } EXPORT_SYMBOL(pci_read_config_dword); int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val) { + if (pci_dev_is_disconnected(dev)) + return -ENODEV; return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val); } EXPORT_SYMBOL(pci_write_config_byte); int pci_write_config_word(const struct pci_dev *dev, int where, u16 val) { + if (pci_dev_is_disconnected(dev)) + return -ENODEV; return pci_bus_write_config_word(dev->bus, dev->devfn, where, val); } EXPORT_SYMBOL(pci_write_config_word); @@ -924,6 +940,8 @@ EXPORT_SYMBOL(pci_write_config_word); int pci_write_config_dword(const struct pci_dev *dev, int where, u32 val) { + if (pci_dev_is_disconnected(dev)) + return -ENODEV; return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val); } EXPORT_SYMBOL(pci_write_config_dword);