diff options
-rw-r--r-- | drivers/net/bnx2.c | 23 | ||||
-rw-r--r-- | drivers/net/tg3.c | 23 | ||||
-rw-r--r-- | include/linux/pci.h | 34 |
3 files changed, 67 insertions, 13 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index bb403887b549..084ef102b8c4 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -7772,15 +7772,26 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp) | |||
7772 | unsigned char val = data[i]; | 7772 | unsigned char val = data[i]; |
7773 | unsigned int block_end; | 7773 | unsigned int block_end; |
7774 | 7774 | ||
7775 | if (val == 0x82 || val == 0x91) { | 7775 | if (val & PCI_VPD_LRDT) { |
7776 | i += PCI_VPD_LRDT_TAG_SIZE + | 7776 | if (i + PCI_VPD_LRDT_TAG_SIZE > BNX2_VPD_LEN) |
7777 | pci_vpd_lrdt_size(&data[i]); | 7777 | break; |
7778 | |||
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 | |||
7778 | continue; | 7792 | continue; |
7779 | } | 7793 | } |
7780 | 7794 | ||
7781 | if (val != 0x90) | ||
7782 | goto vpd_done; | ||
7783 | |||
7784 | block_end = (i + PCI_VPD_LRDT_TAG_SIZE + | 7795 | block_end = (i + PCI_VPD_LRDT_TAG_SIZE + |
7785 | pci_vpd_lrdt_size(&data[i])); | 7796 | pci_vpd_lrdt_size(&data[i])); |
7786 | i += PCI_VPD_LRDT_TAG_SIZE; | 7797 | i += PCI_VPD_LRDT_TAG_SIZE; |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5fccbe459949..ed57a62b3ac8 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -12589,15 +12589,26 @@ static void __devinit tg3_read_partno(struct tg3 *tp) | |||
12589 | unsigned char val = vpd_data[i]; | 12589 | unsigned char val = vpd_data[i]; |
12590 | unsigned int block_end; | 12590 | unsigned int block_end; |
12591 | 12591 | ||
12592 | if (val == 0x82 || val == 0x91) { | 12592 | if (val & PCI_VPD_LRDT) { |
12593 | i += PCI_VPD_LRDT_TAG_SIZE + | 12593 | if (i + PCI_VPD_LRDT_TAG_SIZE > TG3_NVM_VPD_LEN) |
12594 | pci_vpd_lrdt_size(&vpd_data[i]); | 12594 | break; |
12595 | |||
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 | |||
12595 | continue; | 12609 | continue; |
12596 | } | 12610 | } |
12597 | 12611 | ||
12598 | if (val != 0x90) | ||
12599 | goto out_not_found; | ||
12600 | |||
12601 | block_end = i + PCI_VPD_LRDT_TAG_SIZE + | 12612 | block_end = i + PCI_VPD_LRDT_TAG_SIZE + |
12602 | pci_vpd_lrdt_size(&vpd_data[i]); | 12613 | pci_vpd_lrdt_size(&vpd_data[i]); |
12603 | 12614 | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index 6f62a499023f..198d062640b7 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1350,7 +1350,28 @@ static inline bool pci_is_pcie(struct pci_dev *dev) | |||
1350 | void pci_request_acs(void); | 1350 | void pci_request_acs(void); |
1351 | 1351 | ||
1352 | 1352 | ||
1353 | #define PCI_VPD_LRDT_TAG_SIZE 3 | 1353 | #define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */ |
1354 | #define PCI_VPD_LRDT_ID(x) (x | PCI_VPD_LRDT) | ||
1355 | |||
1356 | /* Large Resource Data Type Tag Item Names */ | ||
1357 | #define PCI_VPD_LTIN_ID_STRING 0x02 /* Identifier String */ | ||
1358 | #define PCI_VPD_LTIN_RO_DATA 0x10 /* Read-Only Data */ | ||
1359 | #define PCI_VPD_LTIN_RW_DATA 0x11 /* Read-Write Data */ | ||
1360 | |||
1361 | #define PCI_VPD_LRDT_ID_STRING PCI_VPD_LRDT_ID(PCI_VPD_LTIN_ID_STRING) | ||
1362 | #define PCI_VPD_LRDT_RO_DATA PCI_VPD_LRDT_ID(PCI_VPD_LTIN_RO_DATA) | ||
1363 | #define PCI_VPD_LRDT_RW_DATA PCI_VPD_LRDT_ID(PCI_VPD_LTIN_RW_DATA) | ||
1364 | |||
1365 | /* Small Resource Data Type Tag Item Names */ | ||
1366 | #define PCI_VPD_STIN_END 0x78 /* End */ | ||
1367 | |||
1368 | #define PCI_VPD_SRDT_END PCI_VPD_STIN_END | ||
1369 | |||
1370 | #define PCI_VPD_SRDT_TIN_MASK 0x78 | ||
1371 | #define PCI_VPD_SRDT_LEN_MASK 0x07 | ||
1372 | |||
1373 | #define PCI_VPD_LRDT_TAG_SIZE 3 | ||
1374 | #define PCI_VPD_SRDT_TAG_SIZE 1 | ||
1354 | 1375 | ||
1355 | /** | 1376 | /** |
1356 | * pci_vpd_lrdt_size - Extracts the Large Resource Data Type length | 1377 | * pci_vpd_lrdt_size - Extracts the Large Resource Data Type length |
@@ -1363,5 +1384,16 @@ static inline u16 pci_vpd_lrdt_size(const u8 *lrdt) | |||
1363 | return (u16)lrdt[1] + ((u16)lrdt[2] << 8); | 1384 | return (u16)lrdt[1] + ((u16)lrdt[2] << 8); |
1364 | } | 1385 | } |
1365 | 1386 | ||
1387 | /** | ||
1388 | * pci_vpd_srdt_size - Extracts the Small Resource Data Type length | ||
1389 | * @lrdt: Pointer to the beginning of the Small Resource Data Type tag | ||
1390 | * | ||
1391 | * Returns the extracted Small Resource Data Type length. | ||
1392 | */ | ||
1393 | static inline u8 pci_vpd_srdt_size(const u8 *srdt) | ||
1394 | { | ||
1395 | return (*srdt) & PCI_VPD_SRDT_LEN_MASK; | ||
1396 | } | ||
1397 | |||
1366 | #endif /* __KERNEL__ */ | 1398 | #endif /* __KERNEL__ */ |
1367 | #endif /* LINUX_PCI_H */ | 1399 | #endif /* LINUX_PCI_H */ |