summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/vpd.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c
index 0e7a5e8a8f17..b7bf014ccc5f 100644
--- a/drivers/pci/vpd.c
+++ b/drivers/pci/vpd.c
@@ -296,16 +296,25 @@ void *pci_vpd_alloc(struct pci_dev *dev, unsigned int *size)
}
EXPORT_SYMBOL_GPL(pci_vpd_alloc);
-static int pci_vpd_find_tag(const u8 *buf, unsigned int len, u8 rdt)
+static int pci_vpd_find_tag(const u8 *buf, unsigned int len, u8 rdt, unsigned int *size)
{
int i = 0;
/* look for LRDT tags only, end tag is the only SRDT tag */
while (i + PCI_VPD_LRDT_TAG_SIZE <= len && buf[i] & PCI_VPD_LRDT) {
- if (buf[i] == rdt)
+ unsigned int lrdt_len = pci_vpd_lrdt_size(buf + i);
+ u8 tag = buf[i];
+
+ i += PCI_VPD_LRDT_TAG_SIZE;
+ if (tag == rdt) {
+ if (i + lrdt_len > len)
+ lrdt_len = len - i;
+ if (size)
+ *size = lrdt_len;
return i;
+ }
- i += PCI_VPD_LRDT_TAG_SIZE + pci_vpd_lrdt_size(buf + i);
+ i += lrdt_len;
}
return -ENOENT;
@@ -384,16 +393,10 @@ int pci_vpd_find_ro_info_keyword(const void *buf, unsigned int len,
int ro_start, infokw_start;
unsigned int ro_len, infokw_size;
- ro_start = pci_vpd_find_tag(buf, len, PCI_VPD_LRDT_RO_DATA);
+ ro_start = pci_vpd_find_tag(buf, len, PCI_VPD_LRDT_RO_DATA, &ro_len);
if (ro_start < 0)
return ro_start;
- ro_len = pci_vpd_lrdt_size(buf + ro_start);
- ro_start += PCI_VPD_LRDT_TAG_SIZE;
-
- if (ro_start + ro_len > len)
- ro_len = len - ro_start;
-
infokw_start = pci_vpd_find_info_keyword(buf, ro_start, ro_len, kw);
if (infokw_start < 0)
return infokw_start;