summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHeiner Kallweit <hkallweit1@gmail.com>2021-08-20 15:32:42 -0500
committerBjorn Helgaas <bhelgaas@google.com>2021-08-20 15:48:47 -0500
commit6107e5cb907cffc5576cc1297847f9fc69a8d5d9 (patch)
tree298f8f2585311874a1b60faa149fc009d1cbb5b0 /drivers
parent9e515c9f6c0b6f0ace6f5cf2202b527d745b494d (diff)
downloadlinux-6107e5cb907cffc5576cc1297847f9fc69a8d5d9.tar.bz2
PCI/VPD: Add pci_vpd_check_csum()
VPD checksum information and checksum calculation are specified by PCIe r5.0, sec 6.28.2.2. Therefore checksum handling can and should be moved into the PCI VPD core. Add pci_vpd_check_csum() to validate the VPD checksum. [bhelgaas: split 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')
-rw-r--r--drivers/pci/vpd.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c
index b1d012900f1e..01e57594781e 100644
--- a/drivers/pci/vpd.c
+++ b/drivers/pci/vpd.c
@@ -413,6 +413,29 @@ int pci_vpd_find_ro_info_keyword(const void *buf, unsigned int len,
}
EXPORT_SYMBOL_GPL(pci_vpd_find_ro_info_keyword);
+int pci_vpd_check_csum(const void *buf, unsigned int len)
+{
+ const u8 *vpd = buf;
+ unsigned int size;
+ u8 csum = 0;
+ int rv_start;
+
+ rv_start = pci_vpd_find_ro_info_keyword(buf, len, PCI_VPD_RO_KEYWORD_CHKSUM, &size);
+ if (rv_start == -ENOENT) /* no checksum in VPD */
+ return 1;
+ else if (rv_start < 0)
+ return rv_start;
+
+ if (!size)
+ return -EINVAL;
+
+ while (rv_start >= 0)
+ csum += vpd[rv_start--];
+
+ return csum ? -EILSEQ : 0;
+}
+EXPORT_SYMBOL_GPL(pci_vpd_check_csum);
+
#ifdef CONFIG_PCI_QUIRKS
/*
* Quirk non-zero PCI functions to route VPD access through function 0 for