diff options
author | Heiner Kallweit <hkallweit1@gmail.com> | 2021-08-18 21:00:57 +0200 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2021-08-20 15:48:27 -0500 |
commit | 9e515c9f6c0b6f0ace6f5cf2202b527d745b494d (patch) | |
tree | fef7ba602eec9ebd6382f9052b541d0ce85f6574 /drivers/pci/vpd.c | |
parent | 76f3c032adad86aad26f8ad3eebc993b4ba32138 (diff) |
PCI/VPD: Add pci_vpd_find_ro_info_keyword()
All users of pci_vpd_find_info_keyword() are interested in the VPD RO
section only. In addition all calls are followed by the same activities to
calculate start of tag data area and size of the data area.
Add pci_vpd_find_ro_info_keyword() that combines these functionalities.
pci_vpd_find_info_keyword() can be phased out once all users are converted.
[bhelgaas: split pci_vpd_check_csum() to separate patch]
Link: https://lore.kernel.org/r/1643bd7a-088e-1028-c9b0-9d112cf48d63@gmail.com
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/vpd.c')
-rw-r--r-- | drivers/pci/vpd.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index 7c3a097379bb..b1d012900f1e 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -380,6 +380,39 @@ ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void } EXPORT_SYMBOL(pci_write_vpd); +int pci_vpd_find_ro_info_keyword(const void *buf, unsigned int len, + const char *kw, unsigned int *size) +{ + int ro_start, infokw_start; + unsigned int ro_len, infokw_size; + + ro_start = pci_vpd_find_tag(buf, len, PCI_VPD_LRDT_RO_DATA); + if (ro_start < 0) + return ro_start; + + ro_len = pci_vpd_lrdt_size(buf + ro_start); + ro_start += PCI_VPD_LRDT_TAG_SIZE; + + if (ro_start + ro_len > len) + ro_len = len - ro_start; + + infokw_start = pci_vpd_find_info_keyword(buf, ro_start, ro_len, kw); + if (infokw_start < 0) + return infokw_start; + + infokw_size = pci_vpd_info_field_size(buf + infokw_start); + infokw_start += PCI_VPD_INFO_FLD_HDR_SIZE; + + if (infokw_start + infokw_size > len) + return -EINVAL; + + if (size) + *size = infokw_size; + + return infokw_start; +} +EXPORT_SYMBOL_GPL(pci_vpd_find_ro_info_keyword); + #ifdef CONFIG_PCI_QUIRKS /* * Quirk non-zero PCI functions to route VPD access through function 0 for |