From patchwork Tue Sep 27 20:23:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 9352749 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 1497C6077A for ; Tue, 27 Sep 2016 20:12:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 06C3929034 for ; Tue, 27 Sep 2016 20:12:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EF405290CE; Tue, 27 Sep 2016 20:12:47 +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 6EBC229034 for ; Tue, 27 Sep 2016 20:12:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932573AbcI0UMq (ORCPT ); Tue, 27 Sep 2016 16:12:46 -0400 Received: from mga09.intel.com ([134.134.136.24]:58177 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934281AbcI0UMp (ORCPT ); Tue, 27 Sep 2016 16:12:45 -0400 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga102.jf.intel.com with ESMTP; 27 Sep 2016 13:12:45 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.30,406,1470726000"; d="scan'208";a="884426512" Received: from unknown (HELO localhost.lm.intel.com) ([10.232.112.65]) by orsmga003.jf.intel.com with ESMTP; 27 Sep 2016 13:12:44 -0700 From: Keith Busch To: linux-pci@vger.kernel.org, Bjorn Helgaas Cc: Ralf Baechle , Lukas Wunner , Wei Zhang , Keith Busch Subject: [PATCHv3 3/5] pci: No config access for removed devices Date: Tue, 27 Sep 2016 16:23:33 -0400 Message-Id: <1475007815-28354-4-git-send-email-keith.busch@intel.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1475007815-28354-1-git-send-email-keith.busch@intel.com> References: <1475007815-28354-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 that the PCI device is removed, there is no need to access the device's config space. This patch has all the device config reads and writes return error when in such a state. If the device is not present on a config read, the value returned 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 Cc: Lukas Wunner --- include/linux/pci.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/linux/pci.h b/include/linux/pci.h index 36b759c..7a320ca 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -929,28 +929,46 @@ struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops); static inline int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val) { + if (unlikely(dev->is_removed)) { + *val = ~0; + return -ENODEV; + } return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val); } static inline int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val) { + if (unlikely(dev->is_removed)) { + *val = ~0; + return -ENODEV; + } return pci_bus_read_config_word(dev->bus, dev->devfn, where, val); } static inline int pci_read_config_dword(const struct pci_dev *dev, int where, u32 *val) { + if (unlikely(dev->is_removed)) { + *val = ~0; + return -ENODEV; + } return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val); } static inline int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val) { + if (unlikely(dev->is_removed)) + return -ENODEV; return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val); } static inline int pci_write_config_word(const struct pci_dev *dev, int where, u16 val) { + if (unlikely(dev->is_removed)) + return -ENODEV; return pci_bus_write_config_word(dev->bus, dev->devfn, where, val); } static inline int pci_write_config_dword(const struct pci_dev *dev, int where, u32 val) { + if (unlikely(dev->is_removed)) + return -ENODEV; return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val); }