From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935263AbcLMTxS (ORCPT ); Tue, 13 Dec 2016 14:53:18 -0500 Received: from mx2.suse.de ([195.135.220.15]:54176 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933515AbcLMTxI (ORCPT ); Tue, 13 Dec 2016 14:53:08 -0500 X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" From: Jiri Slaby To: stable@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Alex Williamson , Bjorn Helgaas , Jiri Slaby Subject: [PATCH 3.12 03/38] PCI: Use function 0 VPD for identical functions, regular VPD for others Date: Tue, 13 Dec 2016 20:52:29 +0100 Message-Id: <7d1e51af2cc8c7cb37d647fbdde3f30f1d683c37.1481658746.git.jslaby@suse.cz> X-Mailer: git-send-email 2.11.0 In-Reply-To: <15034b96ec06ee859b67c6cd4e3be569a4ef286b.1481658746.git.jslaby@suse.cz> References: <15034b96ec06ee859b67c6cd4e3be569a4ef286b.1481658746.git.jslaby@suse.cz> In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alex Williamson 3.12-stable review patch. If anyone has any objections, please let me know. =============== commit da2d03ea27f6ed9d2005a67b20dd021ddacf1e4d upstream. 932c435caba8 ("PCI: Add dev_flags bit to access VPD through function 0") added PCI_DEV_FLAGS_VPD_REF_F0. Previously, we set the flag on every non-zero function of quirked devices. If a function turned out to be different from function 0, i.e., it had a different class, vendor ID, or device ID, the flag remained set but we didn't make VPD accessible at all. Flip this around so we only set PCI_DEV_FLAGS_VPD_REF_F0 for functions that are identical to function 0, and allow regular VPD access for any other functions. [bhelgaas: changelog, stable tag] Fixes: 932c435caba8 ("PCI: Add dev_flags bit to access VPD through function 0") Signed-off-by: Alex Williamson Signed-off-by: Bjorn Helgaas Acked-by: Myron Stowe Acked-by: Mark Rustad Signed-off-by: Jiri Slaby --- drivers/pci/access.c | 22 ---------------------- drivers/pci/quirks.c | 20 ++++++++++++++++++-- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 16a022ee54a6..da26bc899d5f 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -395,23 +395,6 @@ static const struct pci_vpd_ops pci_vpd_f0_ops = { .release = pci_vpd_pci22_release, }; -static int pci_vpd_f0_dev_check(struct pci_dev *dev) -{ - struct pci_dev *tdev = pci_get_slot(dev->bus, - PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); - int ret = 0; - - if (!tdev) - return -ENODEV; - if (!tdev->vpd || !tdev->multifunction || - dev->class != tdev->class || dev->vendor != tdev->vendor || - dev->device != tdev->device) - ret = -ENODEV; - - pci_dev_put(tdev); - return ret; -} - int pci_vpd_pci22_init(struct pci_dev *dev) { struct pci_vpd_pci22 *vpd; @@ -420,12 +403,7 @@ int pci_vpd_pci22_init(struct pci_dev *dev) cap = pci_find_capability(dev, PCI_CAP_ID_VPD); if (!cap) return -ENODEV; - if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) { - int ret = pci_vpd_f0_dev_check(dev); - if (ret) - return ret; - } vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC); if (!vpd) return -ENOMEM; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index cb245bd510a2..b1f5f51b0196 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1894,11 +1894,27 @@ static void quirk_netmos(struct pci_dev *dev) DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); +/* + * Quirk non-zero PCI functions to route VPD access through function 0 for + * devices that share VPD resources between functions. The functions are + * expected to be identical devices. + */ static void quirk_f0_vpd_link(struct pci_dev *dev) { - if (!dev->multifunction || !PCI_FUNC(dev->devfn)) + struct pci_dev *f0; + + if (!PCI_FUNC(dev->devfn)) return; - dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0; + + f0 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); + if (!f0) + return; + + if (f0->vpd && dev->class == f0->class && + dev->vendor == f0->vendor && dev->device == f0->device) + dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0; + + pci_dev_put(f0); } DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link); -- 2.11.0