| From: Alex Williamson <alex.williamson@redhat.com> |
| Date: Tue, 15 Sep 2015 11:17:21 -0600 |
| Subject: PCI: Fix devfn for VPD access through function 0 |
| |
| commit 9d9240756e63dd87d6cbf5da8b98ceb8f8192b55 upstream. |
| |
| Commit 932c435caba8 ("PCI: Add dev_flags bit to access VPD through function |
| 0") passes PCI_SLOT(devfn) for the devfn parameter of pci_get_slot(). |
| Generally this works because we're fairly well guaranteed that a PCIe |
| device is at slot address 0, but for the general case, including |
| conventional PCI, it's incorrect. We need to get the slot and then convert |
| it back into a devfn. |
| |
| 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> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/pci/access.c | 9 ++++++--- |
| 1 file changed, 6 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/pci/access.c |
| +++ b/drivers/pci/access.c |
| @@ -358,7 +358,8 @@ static const struct pci_vpd_ops pci_vpd_ |
| static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, |
| void *arg) |
| { |
| - struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); |
| + struct pci_dev *tdev = pci_get_slot(dev->bus, |
| + PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); |
| ssize_t ret; |
| |
| if (!tdev) |
| @@ -372,7 +373,8 @@ static ssize_t pci_vpd_f0_read(struct pc |
| static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count, |
| const void *arg) |
| { |
| - struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); |
| + struct pci_dev *tdev = pci_get_slot(dev->bus, |
| + PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); |
| ssize_t ret; |
| |
| if (!tdev) |
| @@ -391,7 +393,8 @@ static const struct pci_vpd_ops pci_vpd_ |
| |
| static int pci_vpd_f0_dev_check(struct pci_dev *dev) |
| { |
| - struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); |
| + struct pci_dev *tdev = pci_get_slot(dev->bus, |
| + PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); |
| int ret = 0; |
| |
| if (!tdev) |