diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a70147d..6e67a6f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -12055,7 +12055,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, struct net_device *dev; struct tg3 *tp; int err, pm_cap; - const __be32 *fw_data; const char *fw_name = NULL; char str[40]; u64 dma_mask, persist_dma_mask; @@ -12251,27 +12250,27 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, } if (fw_name) { + const __be32 *fw_data; + err = request_firmware(&tp->fw, fw_name, &tp->pdev->dev); if (err) { printk(KERN_ERR "tg3: Failed to load firmware \"%s\"\n", - fw_name); - goto err_out_apeunmap; + fw_name); + goto err_out_iounmap; } fw_data = (void *)tp->fw->data; - /* Firmware blob starts with version numbers, followed by - start address and length. We are setting complete length. - length = end_address_of_bss - start_address_of_text. - Remainder is the blob to be loaded contiguously - from start address. */ + /* Firmware blob starts with version numbers, followed by + start address and _full_ length including BSS sections + (which must be longer than the actual data, of course */ tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */ if (tp->fw_len < (tp->fw->size-12)) { printk(KERN_ERR "tg3: bogus length %d in \"%s\"\n", - tp->fw_len, fw_name); + tp->fw_len, fw_name); err = -EINVAL; - goto err_out_apeunmap; + goto err_out_fw; } } @@ -12300,7 +12299,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, if (err) { printk(KERN_ERR PFX "Could not obtain valid ethernet address, " "aborting.\n"); - goto err_out_iounmap; + goto err_out_fw; } if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) { @@ -12308,7 +12307,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, printk(KERN_ERR PFX "Cannot find proper PCI device " "base address for APE, aborting.\n"); err = -ENODEV; - goto err_out_iounmap; + goto err_out_fw; } tg3reg_base = pci_resource_start(pdev, 2); @@ -12319,7 +12318,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, printk(KERN_ERR PFX "Cannot map APE registers, " "aborting.\n"); err = -ENOMEM; - goto err_out_iounmap; + goto err_out_fw; } tg3_ape_lock_init(tp); @@ -12401,14 +12400,15 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, return 0; err_out_apeunmap: - if (tp->fw) - release_firmware(tp->fw); - if (tp->aperegs) { iounmap(tp->aperegs); tp->aperegs = NULL; } +err_out_fw: + if (tp->fw) + release_firmware(tp->fw); + err_out_iounmap: if (tp->regs) { iounmap(tp->regs); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 435ff9b..5ef31be 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2614,7 +2614,7 @@ struct tg3 { /* firmware info */ const struct firmware *fw; - u32 fw_len; + u32 fw_len; /* includes BSS */ }; #endif /* !(_T3_H) */