1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * File: vpd.c 4 * Purpose: Provide PCI VPD support 5 * 6 * Copyright (C) 2010 Broadcom Corporation. 7 */ 8 9 #include <linux/pci.h> 10 #include <linux/export.h> 11 12 int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt) 13 { 14 int i; 15 16 for (i = off; i < len; ) { 17 u8 val = buf[i]; 18 19 if (val & PCI_VPD_LRDT) { 20 /* Don't return success of the tag isn't complete */ 21 if (i + PCI_VPD_LRDT_TAG_SIZE > len) 22 break; 23 24 if (val == rdt) 25 return i; 26 27 i += PCI_VPD_LRDT_TAG_SIZE + 28 pci_vpd_lrdt_size(&buf[i]); 29 } else { 30 u8 tag = val & ~PCI_VPD_SRDT_LEN_MASK; 31 32 if (tag == rdt) 33 return i; 34 35 if (tag == PCI_VPD_SRDT_END) 36 break; 37 38 i += PCI_VPD_SRDT_TAG_SIZE + 39 pci_vpd_srdt_size(&buf[i]); 40 } 41 } 42 43 return -ENOENT; 44 } 45 EXPORT_SYMBOL_GPL(pci_vpd_find_tag); 46 47 int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off, 48 unsigned int len, const char *kw) 49 { 50 int i; 51 52 for (i = off; i + PCI_VPD_INFO_FLD_HDR_SIZE <= off + len;) { 53 if (buf[i + 0] == kw[0] && 54 buf[i + 1] == kw[1]) 55 return i; 56 57 i += PCI_VPD_INFO_FLD_HDR_SIZE + 58 pci_vpd_info_field_size(&buf[i]); 59 } 60 61 return -ENOENT; 62 } 63 EXPORT_SYMBOL_GPL(pci_vpd_find_info_keyword); 64