diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/Makefile | 2 | ||||
-rw-r--r-- | drivers/pci/iov.c | 15 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 1 | ||||
-rw-r--r-- | drivers/pci/vpd.c | 61 |
4 files changed, 78 insertions, 1 deletions
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 8674c1ebe97..3d102dd87c9 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -4,7 +4,7 @@ obj-y += access.o bus.o probe.o remove.o pci.o \ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ - irq.o + irq.o vpd.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_SYSFS) += slot.o diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index b2a448e19fe..3e5ab2bf6a5 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -706,6 +706,21 @@ irqreturn_t pci_sriov_migration(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pci_sriov_migration); +/** + * pci_num_vf - return number of VFs associated with a PF device_release_driver + * @dev: the PCI device + * + * Returns number of VFs, or 0 if SR-IOV is not enabled. + */ +int pci_num_vf(struct pci_dev *dev) +{ + if (!dev || !dev->is_physfn) + return 0; + else + return dev->sriov->nr_virtfn; +} +EXPORT_SYMBOL_GPL(pci_num_vf); + static int ats_alloc_one(struct pci_dev *dev, int ps) { int pos; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 790eb69a4aa..039e87b7144 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2529,6 +2529,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150d, quirk_i82576_sriov); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov); #endif /* CONFIG_PCI_IOV */ diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c new file mode 100644 index 00000000000..a5a5ca17cfe --- /dev/null +++ b/drivers/pci/vpd.c @@ -0,0 +1,61 @@ +/* + * File: vpd.c + * Purpose: Provide PCI VPD support + * + * Copyright (C) 2010 Broadcom Corporation. + */ + +#include <linux/pci.h> + +int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt) +{ + int i; + + for (i = off; i < len; ) { + u8 val = buf[i]; + + if (val & PCI_VPD_LRDT) { + /* Don't return success of the tag isn't complete */ + if (i + PCI_VPD_LRDT_TAG_SIZE > len) + break; + + if (val == rdt) + return i; + + i += PCI_VPD_LRDT_TAG_SIZE + + pci_vpd_lrdt_size(&buf[i]); + } else { + u8 tag = val & ~PCI_VPD_SRDT_LEN_MASK; + + if (tag == rdt) + return i; + + if (tag == PCI_VPD_SRDT_END) + break; + + i += PCI_VPD_SRDT_TAG_SIZE + + pci_vpd_srdt_size(&buf[i]); + } + } + + return -ENOENT; +} +EXPORT_SYMBOL_GPL(pci_vpd_find_tag); + +int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off, + unsigned int len, const char *kw) +{ + int i; + + for (i = off; i + PCI_VPD_INFO_FLD_HDR_SIZE <= off + len;) { + if (buf[i + 0] == kw[0] && + buf[i + 1] == kw[1]) + return i; + + i += PCI_VPD_INFO_FLD_HDR_SIZE + + pci_vpd_info_field_size(&buf[i]); + } + + return -ENOENT; +} +EXPORT_SYMBOL_GPL(pci_vpd_find_info_keyword); |