| From foo@baz Tue Nov 28 10:58:31 CET 2017 |
| From: Bjorn Helgaas <bhelgaas@google.com> |
| Date: Mon, 2 Jan 2017 14:04:24 -0600 |
| Subject: PCI: Apply _HPX settings only to relevant devices |
| |
| From: Bjorn Helgaas <bhelgaas@google.com> |
| |
| |
| [ Upstream commit 977509f7c5c6fb992ffcdf4291051af343b91645 ] |
| |
| Previously we didn't check the type of device before trying to apply Type 1 |
| (PCI-X) or Type 2 (PCIe) Setting Records from _HPX. |
| |
| We don't support PCI-X Setting Records, so this was harmless, but the |
| warning was useless. |
| |
| We do support PCIe Setting Records, and we didn't check whether a device |
| was PCIe before applying settings. I don't think anything bad happened on |
| non-PCIe devices because pcie_capability_clear_and_set_word(), |
| pcie_cap_has_lnkctl(), etc., would fail before doing any harm. But it's |
| ugly to depend on those internals. |
| |
| Check the device type before attempting to apply Type 1 and Type 2 Setting |
| Records (Type 0 records are applicable to PCI, PCI-X, and PCIe devices). |
| |
| A side benefit is that this prevents useless "not supported" warnings when |
| a BIOS supplies a Type 1 (PCI-X) Setting Record and we try to apply it to |
| every single device: |
| |
| pci 0000:00:00.0: PCI-X settings not supported |
| |
| After this patch, we'll get the warning only when a BIOS supplies a Type 1 |
| record and we have a PCI-X device to which it should be applied. |
| |
| Link: https://bugzilla.kernel.org/show_bug.cgi?id=187731 |
| Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> |
| Signed-off-by: Sasha Levin <alexander.levin@verizon.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/pci/probe.c | 15 +++++++++++++-- |
| 1 file changed, 13 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/pci/probe.c |
| +++ b/drivers/pci/probe.c |
| @@ -1329,8 +1329,16 @@ static void program_hpp_type0(struct pci |
| |
| static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp) |
| { |
| - if (hpp) |
| - dev_warn(&dev->dev, "PCI-X settings not supported\n"); |
| + int pos; |
| + |
| + if (!hpp) |
| + return; |
| + |
| + pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
| + if (!pos) |
| + return; |
| + |
| + dev_warn(&dev->dev, "PCI-X settings not supported\n"); |
| } |
| |
| static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) |
| @@ -1341,6 +1349,9 @@ static void program_hpp_type2(struct pci |
| if (!hpp) |
| return; |
| |
| + if (!pci_is_pcie(dev)) |
| + return; |
| + |
| if (hpp->revision > 1) { |
| dev_warn(&dev->dev, "PCIe settings rev %d not supported\n", |
| hpp->revision); |