diff options
author | Jing Huang <huangj@brocade.com> | 2011-04-13 14:44:03 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-05-01 11:53:49 -0400 |
commit | 61338a0b3493fddfca2980ece4423839748fcbab (patch) | |
tree | 77406ab428762e76063d94de996cbf120a6265d3 /drivers | |
parent | 7dacb64f49848f1f28018fd3e58af8d6ba234960 (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.c | 39 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_im.h | 25 |
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; | |||
57 | int bfa_debugfs_enable = 1; | 57 | int bfa_debugfs_enable = 1; |
58 | int msix_disable_cb = 0, msix_disable_ct = 0; | 58 | int msix_disable_cb = 0, msix_disable_ct = 0; |
59 | 59 | ||
60 | /* Firmware releated */ | ||
60 | u32 bfi_image_ct_fc_size, bfi_image_ct_cna_size, bfi_image_cb_fc_size; | 61 | u32 bfi_image_ct_fc_size, bfi_image_ct_cna_size, bfi_image_cb_fc_size; |
61 | u32 *bfi_image_ct_fc, *bfi_image_ct_cna, *bfi_image_cb_fc; | 62 | u32 *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 | |||
68 | static u32 *bfad_load_fwimg(struct pci_dev *pdev); | ||
69 | static void bfad_free_fwimg(void); | ||
70 | static void bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image, | ||
71 | u32 *bfi_image_size, char *fw_name); | ||
72 | |||
63 | static const char *msix_name_ct[] = { | 73 | static 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 */ |
1553 | u32 * | 1563 | static void |
1554 | bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image, | 1564 | bfad_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 | 1584 | out: | |
1574 | return *bfi_image; | 1585 | release_firmware(fw); |
1575 | |||
1576 | error: | ||
1577 | return NULL; | ||
1578 | } | 1586 | } |
1579 | 1587 | ||
1580 | u32 * | 1588 | static u32 * |
1581 | bfad_get_firmware_buf(struct pci_dev *pdev) | 1589 | bfad_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 | ||
1609 | static void | ||
1610 | bfad_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 | |||
1601 | module_init(bfad_init); | 1620 | module_init(bfad_init); |
1602 | module_exit(bfad_exit); | 1621 | module_exit(bfad_exit); |
1603 | MODULE_LICENSE("GPL"); | 1622 | MODULE_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 | ||
142 | irqreturn_t bfad_intx(int irq, void *dev_id); | 142 | irqreturn_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 | |||
149 | u32 *bfad_get_firmware_buf(struct pci_dev *pdev); | ||
150 | u32 *bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image, | ||
151 | u32 *bfi_image_size, char *fw_name); | ||
152 | |||
153 | static inline u32 * | ||
154 | bfad_load_fwimg(struct pci_dev *pdev) | ||
155 | { | ||
156 | return bfad_get_firmware_buf(pdev); | ||
157 | } | ||
158 | |||
159 | static inline void | ||
160 | bfad_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 |