diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index c2ea05fbbf1d939bcda8d75e0179615ae25f4353..63d0952684fbc069294f48abb29217e3e3636ddd 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -167,15 +167,9 @@ static DEVICE_ATTR_RO(max_link_speed); static ssize_t max_link_width_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct pci_dev *pci_dev = to_pci_dev(dev); - u32 linkcap; - int err; - - err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, &linkcap); - if (err) - return -EINVAL; + struct pci_dev *pdev = to_pci_dev(dev); - return sprintf(buf, "%u\n", (linkcap & PCI_EXP_LNKCAP_MLW) >> 4); + return sprintf(buf, "%u\n", pcie_get_width_cap(pdev)); } static DEVICE_ATTR_RO(max_link_width); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b29d3436ee9f1544ec00e4b8fd2f62a485669c94..43075be79388ad5c8b1deae8011044680d50800e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5190,6 +5190,24 @@ enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev) return PCI_SPEED_UNKNOWN; } +/** + * pcie_get_width_cap - query for the PCI device's link width capability + * @dev: PCI device to query + * + * Query the PCI device width capability. Return the maximum link width + * supported by the device. + */ +enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev) +{ + u32 lnkcap; + + pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap); + if (lnkcap) + return (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4; + + return PCIE_LNK_WIDTH_UNKNOWN; +} + /** * pci_select_bars - Make BAR mask from the type of resource * @dev: the PCI device for which BAR mask is made diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 1186d8be60556ff212357fd20827a11825062e1c..66738f1050c06bf6441ebc2e5ee7591c9d089063 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -262,6 +262,7 @@ void pci_disable_bridge_window(struct pci_dev *dev); "Unknown speed") enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev); +enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev); /* Single Root I/O Virtualization */ struct pci_sriov {