diff options
-rw-r--r-- | drivers/net/bnx2.c | 24 | ||||
-rw-r--r-- | drivers/net/tg3.c | 26 | ||||
-rw-r--r-- | drivers/pci/Makefile | 2 | ||||
-rw-r--r-- | drivers/pci/vpd.c | 43 | ||||
-rw-r--r-- | include/linux/pci.h | 12 |
5 files changed, 65 insertions, 42 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 084ef102b8c4..fd43feb5a350 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -7769,28 +7769,12 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp) | |||
7769 | } | 7769 | } |
7770 | 7770 | ||
7771 | for (i = 0; i <= BNX2_VPD_LEN - 3; ) { | 7771 | for (i = 0; i <= BNX2_VPD_LEN - 3; ) { |
7772 | unsigned char val = data[i]; | ||
7773 | unsigned int block_end; | 7772 | unsigned int block_end; |
7774 | 7773 | ||
7775 | if (val & PCI_VPD_LRDT) { | 7774 | i = pci_vpd_find_tag(data, i, BNX2_VPD_LEN, |
7776 | if (i + PCI_VPD_LRDT_TAG_SIZE > BNX2_VPD_LEN) | 7775 | PCI_VPD_LRDT_RO_DATA); |
7777 | break; | 7776 | if (i < 0) |
7778 | 7777 | break; | |
7779 | if (val != PCI_VPD_LRDT_RO_DATA) { | ||
7780 | i += PCI_VPD_LRDT_TAG_SIZE + | ||
7781 | pci_vpd_lrdt_size(&data[i]); | ||
7782 | |||
7783 | continue; | ||
7784 | } | ||
7785 | } else { | ||
7786 | if ((val & PCI_VPD_SRDT_TIN_MASK) == PCI_VPD_STIN_END) | ||
7787 | break; | ||
7788 | |||
7789 | i += PCI_VPD_SRDT_TAG_SIZE + | ||
7790 | pci_vpd_srdt_size(&data[i]); | ||
7791 | |||
7792 | continue; | ||
7793 | } | ||
7794 | 7778 | ||
7795 | block_end = (i + PCI_VPD_LRDT_TAG_SIZE + | 7779 | block_end = (i + PCI_VPD_LRDT_TAG_SIZE + |
7796 | pci_vpd_lrdt_size(&data[i])); | 7780 | pci_vpd_lrdt_size(&data[i])); |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ed57a62b3ac8..76ad141ab448 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -12547,7 +12547,7 @@ skip_phy_reset: | |||
12547 | static void __devinit tg3_read_partno(struct tg3 *tp) | 12547 | static void __devinit tg3_read_partno(struct tg3 *tp) |
12548 | { | 12548 | { |
12549 | unsigned char vpd_data[TG3_NVM_VPD_LEN]; /* in little-endian format */ | 12549 | unsigned char vpd_data[TG3_NVM_VPD_LEN]; /* in little-endian format */ |
12550 | unsigned int i; | 12550 | int i; |
12551 | u32 magic; | 12551 | u32 magic; |
12552 | 12552 | ||
12553 | if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) || | 12553 | if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) || |
@@ -12586,28 +12586,12 @@ static void __devinit tg3_read_partno(struct tg3 *tp) | |||
12586 | 12586 | ||
12587 | /* Now parse and find the part number. */ | 12587 | /* Now parse and find the part number. */ |
12588 | for (i = 0; i < TG3_NVM_VPD_LEN - 2; ) { | 12588 | for (i = 0; i < TG3_NVM_VPD_LEN - 2; ) { |
12589 | unsigned char val = vpd_data[i]; | ||
12590 | unsigned int block_end; | 12589 | unsigned int block_end; |
12591 | 12590 | ||
12592 | if (val & PCI_VPD_LRDT) { | 12591 | i = pci_vpd_find_tag(vpd_data, i, TG3_NVM_VPD_LEN, |
12593 | if (i + PCI_VPD_LRDT_TAG_SIZE > TG3_NVM_VPD_LEN) | 12592 | PCI_VPD_LRDT_RO_DATA); |
12594 | break; | 12593 | if (i < 0) |
12595 | 12594 | break; | |
12596 | if (val != PCI_VPD_LRDT_RO_DATA) { | ||
12597 | i += PCI_VPD_LRDT_TAG_SIZE + | ||
12598 | pci_vpd_lrdt_size(&vpd_data[i]); | ||
12599 | |||
12600 | continue; | ||
12601 | } | ||
12602 | } else { | ||
12603 | if ((val & PCI_VPD_SRDT_TIN_MASK) == PCI_VPD_STIN_END) | ||
12604 | break; | ||
12605 | |||
12606 | i += PCI_VPD_SRDT_TAG_SIZE + | ||
12607 | pci_vpd_srdt_size(&vpd_data[i]); | ||
12608 | |||
12609 | continue; | ||
12610 | } | ||
12611 | 12595 | ||
12612 | block_end = i + PCI_VPD_LRDT_TAG_SIZE + | 12596 | block_end = i + PCI_VPD_LRDT_TAG_SIZE + |
12613 | pci_vpd_lrdt_size(&vpd_data[i]); | 12597 | pci_vpd_lrdt_size(&vpd_data[i]); |
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 4df48d58eaa6..b2f6d777a084 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \ | 5 | obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \ |
6 | pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ | 6 | pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ |
7 | irq.o | 7 | irq.o vpd.o |
8 | obj-$(CONFIG_PROC_FS) += proc.o | 8 | obj-$(CONFIG_PROC_FS) += proc.o |
9 | obj-$(CONFIG_SYSFS) += slot.o | 9 | obj-$(CONFIG_SYSFS) += slot.o |
10 | 10 | ||
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); | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index 198d062640b7..e30ceea7345b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1395,5 +1395,17 @@ static inline u8 pci_vpd_srdt_size(const u8 *srdt) | |||
1395 | return (*srdt) & PCI_VPD_SRDT_LEN_MASK; | 1395 | return (*srdt) & PCI_VPD_SRDT_LEN_MASK; |
1396 | } | 1396 | } |
1397 | 1397 | ||
1398 | /** | ||
1399 | * pci_vpd_find_tag - Locates the Resource Data Type tag provided | ||
1400 | * @buf: Pointer to buffered vpd data | ||
1401 | * @off: The offset into the buffer at which to begin the search | ||
1402 | * @len: The length of the vpd buffer | ||
1403 | * @rdt: The Resource Data Type to search for | ||
1404 | * | ||
1405 | * Returns the index where the Resource Data Type was found or | ||
1406 | * -ENOENT otherwise. | ||
1407 | */ | ||
1408 | int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt); | ||
1409 | |||
1398 | #endif /* __KERNEL__ */ | 1410 | #endif /* __KERNEL__ */ |
1399 | #endif /* LINUX_PCI_H */ | 1411 | #endif /* LINUX_PCI_H */ |