aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJing Huang <huangj@brocade.com>2011-04-13 14:44:03 -0400
committerJames Bottomley <James.Bottomley@suse.de>2011-05-01 11:53:49 -0400
commit61338a0b3493fddfca2980ece4423839748fcbab (patch)
tree77406ab428762e76063d94de996cbf120a6265d3 /drivers
parent7dacb64f49848f1f28018fd3e58af8d6ba234960 (diff)
[SCSI] bfa: firmware download fix
This patch includes fixes for two issues releated to firmware download implementation: 1) Merged memory leak fix provided by Jesper Juhl <jj@chaosbits.net>. Basically we need to call release_firmware() after request_firmware(). 2) fixed issues with the firmware download interface as pointed out by Rolf Eike Beer <eike@sf-mail.de> in linux-scsi. Rearranged the code and fixed related function protypes. Signed-off-by: Jing Huang <huangj@brocade.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/bfa/bfad.c39
-rw-r--r--drivers/scsi/bfa/bfad_im.h25
2 files changed, 29 insertions, 35 deletions
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index 0fd510a01561..d9360bf18d33 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -57,9 +57,19 @@ int pcie_max_read_reqsz;
57int bfa_debugfs_enable = 1; 57int bfa_debugfs_enable = 1;
58int msix_disable_cb = 0, msix_disable_ct = 0; 58int msix_disable_cb = 0, msix_disable_ct = 0;
59 59
60/* Firmware releated */
60u32 bfi_image_ct_fc_size, bfi_image_ct_cna_size, bfi_image_cb_fc_size; 61u32 bfi_image_ct_fc_size, bfi_image_ct_cna_size, bfi_image_cb_fc_size;
61u32 *bfi_image_ct_fc, *bfi_image_ct_cna, *bfi_image_cb_fc; 62u32 *bfi_image_ct_fc, *bfi_image_ct_cna, *bfi_image_cb_fc;
62 63
64#define BFAD_FW_FILE_CT_FC "ctfw_fc.bin"
65#define BFAD_FW_FILE_CT_CNA "ctfw_cna.bin"
66#define BFAD_FW_FILE_CB_FC "cbfw_fc.bin"
67
68static u32 *bfad_load_fwimg(struct pci_dev *pdev);
69static void bfad_free_fwimg(void);
70static void bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
71 u32 *bfi_image_size, char *fw_name);
72
63static const char *msix_name_ct[] = { 73static const char *msix_name_ct[] = {
64 "cpe0", "cpe1", "cpe2", "cpe3", 74 "cpe0", "cpe1", "cpe2", "cpe3",
65 "rme0", "rme1", "rme2", "rme3", 75 "rme0", "rme1", "rme2", "rme3",
@@ -1550,7 +1560,7 @@ bfad_exit(void)
1550} 1560}
1551 1561
1552/* Firmware handling */ 1562/* Firmware handling */
1553u32 * 1563static void
1554bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image, 1564bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
1555 u32 *bfi_image_size, char *fw_name) 1565 u32 *bfi_image_size, char *fw_name)
1556{ 1566{
@@ -1558,27 +1568,25 @@ bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
1558 1568
1559 if (request_firmware(&fw, fw_name, &pdev->dev)) { 1569 if (request_firmware(&fw, fw_name, &pdev->dev)) {
1560 printk(KERN_ALERT "Can't locate firmware %s\n", fw_name); 1570 printk(KERN_ALERT "Can't locate firmware %s\n", fw_name);
1561 goto error; 1571 *bfi_image = NULL;
1572 goto out;
1562 } 1573 }
1563 1574
1564 *bfi_image = vmalloc(fw->size); 1575 *bfi_image = vmalloc(fw->size);
1565 if (NULL == *bfi_image) { 1576 if (NULL == *bfi_image) {
1566 printk(KERN_ALERT "Fail to allocate buffer for fw image " 1577 printk(KERN_ALERT "Fail to allocate buffer for fw image "
1567 "size=%x!\n", (u32) fw->size); 1578 "size=%x!\n", (u32) fw->size);
1568 goto error; 1579 goto out;
1569 } 1580 }
1570 1581
1571 memcpy(*bfi_image, fw->data, fw->size); 1582 memcpy(*bfi_image, fw->data, fw->size);
1572 *bfi_image_size = fw->size/sizeof(u32); 1583 *bfi_image_size = fw->size/sizeof(u32);
1573 1584out:
1574 return *bfi_image; 1585 release_firmware(fw);
1575
1576error:
1577 return NULL;
1578} 1586}
1579 1587
1580u32 * 1588static u32 *
1581bfad_get_firmware_buf(struct pci_dev *pdev) 1589bfad_load_fwimg(struct pci_dev *pdev)
1582{ 1590{
1583 if (pdev->device == BFA_PCI_DEVICE_ID_CT_FC) { 1591 if (pdev->device == BFA_PCI_DEVICE_ID_CT_FC) {
1584 if (bfi_image_ct_fc_size == 0) 1592 if (bfi_image_ct_fc_size == 0)
@@ -1598,6 +1606,17 @@ bfad_get_firmware_buf(struct pci_dev *pdev)
1598 } 1606 }
1599} 1607}
1600 1608
1609static void
1610bfad_free_fwimg(void)
1611{
1612 if (bfi_image_ct_fc_size && bfi_image_ct_fc)
1613 vfree(bfi_image_ct_fc);
1614 if (bfi_image_ct_cna_size && bfi_image_ct_cna)
1615 vfree(bfi_image_ct_cna);
1616 if (bfi_image_cb_fc_size && bfi_image_cb_fc)
1617 vfree(bfi_image_cb_fc);
1618}
1619
1601module_init(bfad_init); 1620module_init(bfad_init);
1602module_exit(bfad_exit); 1621module_exit(bfad_exit);
1603MODULE_LICENSE("GPL"); 1622MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h
index bfee63b16fa9..c296c8968511 100644
--- a/drivers/scsi/bfa/bfad_im.h
+++ b/drivers/scsi/bfa/bfad_im.h
@@ -141,29 +141,4 @@ extern struct device_attribute *bfad_im_vport_attrs[];
141 141
142irqreturn_t bfad_intx(int irq, void *dev_id); 142irqreturn_t bfad_intx(int irq, void *dev_id);
143 143
144/* Firmware releated */
145#define BFAD_FW_FILE_CT_FC "ctfw_fc.bin"
146#define BFAD_FW_FILE_CT_CNA "ctfw_cna.bin"
147#define BFAD_FW_FILE_CB_FC "cbfw_fc.bin"
148
149u32 *bfad_get_firmware_buf(struct pci_dev *pdev);
150u32 *bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
151 u32 *bfi_image_size, char *fw_name);
152
153static inline u32 *
154bfad_load_fwimg(struct pci_dev *pdev)
155{
156 return bfad_get_firmware_buf(pdev);
157}
158
159static inline void
160bfad_free_fwimg(void)
161{
162 if (bfi_image_ct_fc_size && bfi_image_ct_fc)
163 vfree(bfi_image_ct_fc);
164 if (bfi_image_ct_cna_size && bfi_image_ct_cna)
165 vfree(bfi_image_ct_cna);
166 if (bfi_image_cb_fc_size && bfi_image_cb_fc)
167 vfree(bfi_image_cb_fc);
168}
169#endif 144#endif