vpd.c 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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. int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt)
  9. {
  10. int i;
  11. for (i = off; i < len; ) {
  12. u8 val = buf[i];
  13. if (val & PCI_VPD_LRDT) {
  14. /* Don't return success of the tag isn't complete */
  15. if (i + PCI_VPD_LRDT_TAG_SIZE > len)
  16. break;
  17. if (val == rdt)
  18. return i;
  19. i += PCI_VPD_LRDT_TAG_SIZE +
  20. pci_vpd_lrdt_size(&buf[i]);
  21. } else {
  22. u8 tag = val & ~PCI_VPD_SRDT_LEN_MASK;
  23. if (tag == rdt)
  24. return i;
  25. if (tag == PCI_VPD_SRDT_END)
  26. break;
  27. i += PCI_VPD_SRDT_TAG_SIZE +
  28. pci_vpd_srdt_size(&buf[i]);
  29. }
  30. }
  31. return -ENOENT;
  32. }
  33. EXPORT_SYMBOL_GPL(pci_vpd_find_tag);
  34. int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off,
  35. unsigned int len, const char *kw)
  36. {
  37. int i;
  38. for (i = off; i + PCI_VPD_INFO_FLD_HDR_SIZE <= off + len;) {
  39. if (buf[i + 0] == kw[0] &&
  40. buf[i + 1] == kw[1])
  41. return i;
  42. i += PCI_VPD_INFO_FLD_HDR_SIZE +
  43. pci_vpd_info_field_size(&buf[i]);
  44. }
  45. return -ENOENT;
  46. }
  47. EXPORT_SYMBOL_GPL(pci_vpd_find_info_keyword);