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