diff options
Diffstat (limited to 'drivers/pci/vpd.c')
-rw-r--r-- | drivers/pci/vpd.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c new file mode 100644 index 000000000000..6bc554576f8d --- /dev/null +++ b/drivers/pci/vpd.c | |||
@@ -0,0 +1,43 @@ | |||
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 | |||
10 | int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt) | ||
11 | { | ||
12 | int i; | ||
13 | |||
14 | for (i = off; i < len; ) { | ||
15 | u8 val = buf[i]; | ||
16 | |||
17 | if (val & PCI_VPD_LRDT) { | ||
18 | /* Don't return success of the tag isn't complete */ | ||
19 | if (i + PCI_VPD_LRDT_TAG_SIZE > len) | ||
20 | break; | ||
21 | |||
22 | if (val == rdt) | ||
23 | return i; | ||
24 | |||
25 | i += PCI_VPD_LRDT_TAG_SIZE + | ||
26 | pci_vpd_lrdt_size(&buf[i]); | ||
27 | } else { | ||
28 | u8 tag = val & ~PCI_VPD_SRDT_LEN_MASK; | ||
29 | |||
30 | if (tag == rdt) | ||
31 | return i; | ||
32 | |||
33 | if (tag == PCI_VPD_SRDT_END) | ||
34 | break; | ||
35 | |||
36 | i += PCI_VPD_SRDT_TAG_SIZE + | ||
37 | pci_vpd_srdt_size(&buf[i]); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | return -ENOENT; | ||
42 | } | ||
43 | EXPORT_SYMBOL_GPL(pci_vpd_find_tag); | ||