diff options
author | Alex Williamson <alex.williamson@redhat.com> | 2015-09-16 00:24:46 -0400 |
---|---|---|
committer | Bjorn Helgaas <helgaas@kernel.org> | 2015-09-24 18:06:32 -0400 |
commit | da2d03ea27f6ed9d2005a67b20dd021ddacf1e4d (patch) | |
tree | 5ed4545d7fd11df195a195055ff0cdf43dcee378 /drivers/pci/access.c | |
parent | 9d9240756e63dd87d6cbf5da8b98ceb8f8192b55 (diff) |
PCI: Use function 0 VPD for identical functions, regular VPD for others
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 <alex.williamson@redhat.com>
Signed-off-by: Bjorn Helgaas <helgaas@kernel.org>
Acked-by: Myron Stowe <myron.stowe@redhat.com>
Acked-by: Mark Rustad <mark.d.rustad@intel.com>
CC: stable@vger.kernel.org
Diffstat (limited to 'drivers/pci/access.c')
-rw-r--r-- | drivers/pci/access.c | 22 |
1 files changed, 0 insertions, 22 deletions
diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 5a5f0a7ba801..59ac36fe7c42 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c | |||
@@ -475,23 +475,6 @@ static const struct pci_vpd_ops pci_vpd_f0_ops = { | |||
475 | .release = pci_vpd_pci22_release, | 475 | .release = pci_vpd_pci22_release, |
476 | }; | 476 | }; |
477 | 477 | ||
478 | static int pci_vpd_f0_dev_check(struct pci_dev *dev) | ||
479 | { | ||
480 | struct pci_dev *tdev = pci_get_slot(dev->bus, | ||
481 | PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); | ||
482 | int ret = 0; | ||
483 | |||
484 | if (!tdev) | ||
485 | return -ENODEV; | ||
486 | if (!tdev->vpd || !tdev->multifunction || | ||
487 | dev->class != tdev->class || dev->vendor != tdev->vendor || | ||
488 | dev->device != tdev->device) | ||
489 | ret = -ENODEV; | ||
490 | |||
491 | pci_dev_put(tdev); | ||
492 | return ret; | ||
493 | } | ||
494 | |||
495 | int pci_vpd_pci22_init(struct pci_dev *dev) | 478 | int pci_vpd_pci22_init(struct pci_dev *dev) |
496 | { | 479 | { |
497 | struct pci_vpd_pci22 *vpd; | 480 | struct pci_vpd_pci22 *vpd; |
@@ -500,12 +483,7 @@ int pci_vpd_pci22_init(struct pci_dev *dev) | |||
500 | cap = pci_find_capability(dev, PCI_CAP_ID_VPD); | 483 | cap = pci_find_capability(dev, PCI_CAP_ID_VPD); |
501 | if (!cap) | 484 | if (!cap) |
502 | return -ENODEV; | 485 | return -ENODEV; |
503 | if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) { | ||
504 | int ret = pci_vpd_f0_dev_check(dev); | ||
505 | 486 | ||
506 | if (ret) | ||
507 | return ret; | ||
508 | } | ||
509 | vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC); | 487 | vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC); |
510 | if (!vpd) | 488 | if (!vpd) |
511 | return -ENOMEM; | 489 | return -ENOMEM; |