diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-05-16 16:49:49 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-05-25 11:12:41 -0400 |
commit | 75813bde1f671aaab3185a9438da7730d356cea6 (patch) | |
tree | b5d6d8dd478065d860d9b13a731562460aa98550 /drivers/net | |
parent | f4c37176ef555560a1d13bc4bf2cf3debd442f40 (diff) |
iwlwifi: fix memory leak if opmode fails to init
If drv->op_mode is NULL after trying to init the
opmode, we go to the wrong label. Fix this, and
clean up the code a bit.
Reviewed-by: Gregory Greenman <gregory.greenman@intel.com>
Reviewed-by: Guy Cohen <guy.cohen@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-drv.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 3c72bad0ae56..d742900969ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -657,17 +657,17 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
657 | return -EINVAL; | 657 | return -EINVAL; |
658 | } | 658 | } |
659 | 659 | ||
660 | static int alloc_pci_desc(struct iwl_drv *drv, | 660 | static int iwl_alloc_ucode(struct iwl_drv *drv, |
661 | struct iwl_firmware_pieces *pieces, | 661 | struct iwl_firmware_pieces *pieces, |
662 | enum iwl_ucode_type type) | 662 | enum iwl_ucode_type type) |
663 | { | 663 | { |
664 | int i; | 664 | int i; |
665 | for (i = 0; | 665 | for (i = 0; |
666 | i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i); | 666 | i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i); |
667 | i++) | 667 | i++) |
668 | if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]), | 668 | if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]), |
669 | get_sec(pieces, type, i))) | 669 | get_sec(pieces, type, i))) |
670 | return -1; | 670 | return -ENOMEM; |
671 | return 0; | 671 | return 0; |
672 | } | 672 | } |
673 | 673 | ||
@@ -825,8 +825,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
825 | * 1) unmodified from disk | 825 | * 1) unmodified from disk |
826 | * 2) backup cache for save/restore during power-downs */ | 826 | * 2) backup cache for save/restore during power-downs */ |
827 | for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) | 827 | for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) |
828 | if (alloc_pci_desc(drv, &pieces, i)) | 828 | if (iwl_alloc_ucode(drv, &pieces, i)) |
829 | goto err_pci_alloc; | 829 | goto out_free_fw; |
830 | 830 | ||
831 | /* Now that we can no longer fail, copy information */ | 831 | /* Now that we can no longer fail, copy information */ |
832 | 832 | ||
@@ -866,7 +866,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
866 | drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw); | 866 | drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw); |
867 | 867 | ||
868 | if (!drv->op_mode) | 868 | if (!drv->op_mode) |
869 | goto out_unbind; | 869 | goto out_free_fw; |
870 | 870 | ||
871 | return; | 871 | return; |
872 | 872 | ||
@@ -877,7 +877,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
877 | goto out_unbind; | 877 | goto out_unbind; |
878 | return; | 878 | return; |
879 | 879 | ||
880 | err_pci_alloc: | 880 | out_free_fw: |
881 | IWL_ERR(drv, "failed to allocate pci memory\n"); | 881 | IWL_ERR(drv, "failed to allocate pci memory\n"); |
882 | iwl_dealloc_ucode(drv); | 882 | iwl_dealloc_ucode(drv); |
883 | release_firmware(ucode_raw); | 883 | release_firmware(ucode_raw); |