From patchwork Tue Nov 26 09:09:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Gordeev X-Patchwork-Id: 3241251 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id EB9B2C045B for ; Tue, 26 Nov 2013 20:53:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0748120445 for ; Tue, 26 Nov 2013 20:53:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1F9912041B for ; Tue, 26 Nov 2013 20:53:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757955Ab3KZUxv (ORCPT ); Tue, 26 Nov 2013 15:53:51 -0500 Received: from 6.77.broadband6.iol.cz ([88.101.77.6]:52486 "EHLO dhcp-26-207.brq.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1757808Ab3KZUxu (ORCPT ); Tue, 26 Nov 2013 15:53:50 -0500 Received: from dhcp-26-207.brq.redhat.com (localhost [127.0.0.1]) by dhcp-26-207.brq.redhat.com (8.14.5/8.14.5) with ESMTP id rAQ9Akj4025373; Tue, 26 Nov 2013 10:10:47 +0100 Received: (from agordeev@localhost) by dhcp-26-207.brq.redhat.com (8.14.5/8.14.5/Submit) id rAQ9Akc8025372; Tue, 26 Nov 2013 10:10:46 +0100 From: Alexander Gordeev To: linux-kernel@vger.kernel.org Cc: Alexander Gordeev , Bjorn Helgaas , Michael Ellerman , Benjamin Herrenschmidt , Tejun Heo , Ben Hutchings , David Laight , Mark Lord , "H. Peter Anvin" , linux-pci@vger.kernel.org Subject: [PATCH v3 10/11] PCI/MSI: Convert pci_msix_table_size() to a public interface Date: Tue, 26 Nov 2013 10:09:59 +0100 Message-Id: <4c879b0928ded8b4c9d2fab3fc413b98d34d8c7c.1385399393.git.agordeev@redhat.com> X-Mailer: git-send-email 1.7.7.6 In-Reply-To: References: Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Make pci_msix_table_size() function to return a negative errno if device does not support MSI-X interrupts. After this update pci_msix_table_size() can fail and callers must always check the returned value. This update is needed to create a consistent MSI-X counterpart for pci_get_msi_cap() MSI interface. Device drivers can use this function to obtain maximum number of MSI-X interrupts the device supports and i.e. use that number in a following call to pci_enable_msix() interface. The only user of pci_msix_table_size() function is PCI-Express port driver, which is also updated by this change. Signed-off-by: Alexander Gordeev Reviewed-by: Tejun Heo --- Documentation/PCI/MSI-HOWTO.txt | 13 +++++++++++++ drivers/pci/msi.c | 12 ++++++++++-- drivers/pci/pcie/portdrv_core.c | 5 +++-- include/linux/pci.h | 2 +- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index 1fe4900..5955389 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt @@ -243,6 +243,19 @@ MSI-X Table. This address is mapped by the PCI subsystem, and should not be accessed directly by the device driver. If the driver wishes to mask or unmask an interrupt, it should call disable_irq() / enable_irq(). +4.3.4 pci_msix_table_size + +int pci_msix_table_size(struct pci_dev *dev) + +This function could be used to retrieve number of entries in the device +MSI-X table. + +If this function returns a negative number, it indicates the device is +not capable of sending MSI-Xs. + +If this function returns a positive number, it indicates the maximum +number of MSI-X interrupt vectors that could be allocated. + 4.4 Handling devices implementing both MSI and MSI-X capabilities If a device implements both MSI and MSI-X capabilities, it can diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index e4b02ac..6fe0add 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -932,17 +932,23 @@ EXPORT_SYMBOL(pci_disable_msi); /** * pci_msix_table_size - return the number of device's MSI-X table entries * @dev: pointer to the pci_dev data structure of MSI-X device function - */ + + * This function returns the number of device's MSI-X table entries and + * therefore the number of MSI-X vectors device is capable to send. + * It returns a negative errno if the device is not capable sending MSI-X + * interrupts. + **/ int pci_msix_table_size(struct pci_dev *dev) { u16 control; if (!dev->msix_cap) - return 0; + return -EINVAL; pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); return msix_table_size(control); } +EXPORT_SYMBOL(pci_msix_table_size); /** * pci_enable_msix - configure device's MSI-X capability structure @@ -972,6 +978,8 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) return status; nr_entries = pci_msix_table_size(dev); + if (nr_entries < 0) + return nr_entries; if (nvec > nr_entries) return nr_entries; diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 08d131f..5bebeec 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -80,8 +80,9 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) u32 reg32; nr_entries = pci_msix_table_size(dev); - if (!nr_entries) - return -EINVAL; + if (nr_entries < 0) + return nr_entries; + BUG_ON(!nr_entries); if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES) nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES; diff --git a/include/linux/pci.h b/include/linux/pci.h index 9ab1692..8af1217 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1172,7 +1172,7 @@ static inline void pci_disable_msi(struct pci_dev *dev) static inline int pci_msix_table_size(struct pci_dev *dev) { - return 0; + return -ENOSYS; } static inline int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)