vpd.c 1.2 KB

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