diff options
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r-- | drivers/pci/quirks.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6a30252cd79f..b03373fd05ca 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -1907,11 +1907,27 @@ static void quirk_netmos(struct pci_dev *dev) | |||
1907 | DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, | 1907 | DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, |
1908 | PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); | 1908 | PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); |
1909 | 1909 | ||
1910 | /* | ||
1911 | * Quirk non-zero PCI functions to route VPD access through function 0 for | ||
1912 | * devices that share VPD resources between functions. The functions are | ||
1913 | * expected to be identical devices. | ||
1914 | */ | ||
1910 | static void quirk_f0_vpd_link(struct pci_dev *dev) | 1915 | static void quirk_f0_vpd_link(struct pci_dev *dev) |
1911 | { | 1916 | { |
1912 | if (!dev->multifunction || !PCI_FUNC(dev->devfn)) | 1917 | struct pci_dev *f0; |
1918 | |||
1919 | if (!PCI_FUNC(dev->devfn)) | ||
1913 | return; | 1920 | return; |
1914 | dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0; | 1921 | |
1922 | f0 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); | ||
1923 | if (!f0) | ||
1924 | return; | ||
1925 | |||
1926 | if (f0->vpd && dev->class == f0->class && | ||
1927 | dev->vendor == f0->vendor && dev->device == f0->device) | ||
1928 | dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0; | ||
1929 | |||
1930 | pci_dev_put(f0); | ||
1915 | } | 1931 | } |
1916 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, | 1932 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, |
1917 | PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link); | 1933 | PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link); |