Commit fcdf95cb authored by Barak Witkowski's avatar Barak Witkowski Committed by David S. Miller

bnx2x: handle vpd data longer than 128 bytes

Signed-off-by: default avatarBarak Witkowski <barak@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent de93cb2e
...@@ -9931,30 +9931,49 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) ...@@ -9931,30 +9931,49 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
static void __devinit bnx2x_read_fwinfo(struct bnx2x *bp) static void __devinit bnx2x_read_fwinfo(struct bnx2x *bp)
{ {
int cnt, i, block_end, rodi; int cnt, i, block_end, rodi;
char vpd_data[BNX2X_VPD_LEN+1]; char vpd_start[BNX2X_VPD_LEN+1];
char str_id_reg[VENDOR_ID_LEN+1]; char str_id_reg[VENDOR_ID_LEN+1];
char str_id_cap[VENDOR_ID_LEN+1]; char str_id_cap[VENDOR_ID_LEN+1];
char *vpd_data;
char *vpd_extended_data = NULL;
u8 len; u8 len;
cnt = pci_read_vpd(bp->pdev, 0, BNX2X_VPD_LEN, vpd_data); cnt = pci_read_vpd(bp->pdev, 0, BNX2X_VPD_LEN, vpd_start);
memset(bp->fw_ver, 0, sizeof(bp->fw_ver)); memset(bp->fw_ver, 0, sizeof(bp->fw_ver));
if (cnt < BNX2X_VPD_LEN) if (cnt < BNX2X_VPD_LEN)
goto out_not_found; goto out_not_found;
i = pci_vpd_find_tag(vpd_data, 0, BNX2X_VPD_LEN, /* VPD RO tag should be first tag after identifier string, hence
* we should be able to find it in first BNX2X_VPD_LEN chars
*/
i = pci_vpd_find_tag(vpd_start, 0, BNX2X_VPD_LEN,
PCI_VPD_LRDT_RO_DATA); PCI_VPD_LRDT_RO_DATA);
if (i < 0) if (i < 0)
goto out_not_found; goto out_not_found;
block_end = i + PCI_VPD_LRDT_TAG_SIZE + block_end = i + PCI_VPD_LRDT_TAG_SIZE +
pci_vpd_lrdt_size(&vpd_data[i]); pci_vpd_lrdt_size(&vpd_start[i]);
i += PCI_VPD_LRDT_TAG_SIZE; i += PCI_VPD_LRDT_TAG_SIZE;
if (block_end > BNX2X_VPD_LEN) if (block_end > BNX2X_VPD_LEN) {
goto out_not_found; vpd_extended_data = kmalloc(block_end, GFP_KERNEL);
if (vpd_extended_data == NULL)
goto out_not_found;
/* read rest of vpd image into vpd_extended_data */
memcpy(vpd_extended_data, vpd_start, BNX2X_VPD_LEN);
cnt = pci_read_vpd(bp->pdev, BNX2X_VPD_LEN,
block_end - BNX2X_VPD_LEN,
vpd_extended_data + BNX2X_VPD_LEN);
if (cnt < (block_end - BNX2X_VPD_LEN))
goto out_not_found;
vpd_data = vpd_extended_data;
} else
vpd_data = vpd_start;
/* now vpd_data holds full vpd content in both cases */
rodi = pci_vpd_find_info_keyword(vpd_data, i, block_end, rodi = pci_vpd_find_info_keyword(vpd_data, i, block_end,
PCI_VPD_RO_KEYWORD_MFR_ID); PCI_VPD_RO_KEYWORD_MFR_ID);
...@@ -9986,9 +10005,11 @@ static void __devinit bnx2x_read_fwinfo(struct bnx2x *bp) ...@@ -9986,9 +10005,11 @@ static void __devinit bnx2x_read_fwinfo(struct bnx2x *bp)
bp->fw_ver[len] = ' '; bp->fw_ver[len] = ' ';
} }
} }
kfree(vpd_extended_data);
return; return;
} }
out_not_found: out_not_found:
kfree(vpd_extended_data);
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment