diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-04-29 10:41:53 -0400 |
---|---|---|
committer | Reinette Chatre <reinette.chatre@intel.com> | 2010-05-10 17:56:14 -0400 |
commit | 562db532760827f6ce30801a08e6b568848bc9f2 (patch) | |
tree | 42c3995c06d7bd7837db4d4862387fa1f72fd2aa | |
parent | 79733a865c7fd778ce45e3503962b3a875b0a153 (diff) |
iwlagn: wait for asynchronous firmware loading
When we kick off a firmware loading process,
and then unbind from the pci device right
away, we get into trouble. Avoid that by
waiting for the firmware loading to finish
(whether successfully or not) before the
unbind in iwl_pci_remove.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 2 |
2 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ba0fdba602cd..ae8eb09f8011 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1741,6 +1741,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1741 | 1741 | ||
1742 | /* We have our copies now, allow OS release its copies */ | 1742 | /* We have our copies now, allow OS release its copies */ |
1743 | release_firmware(ucode_raw); | 1743 | release_firmware(ucode_raw); |
1744 | complete(&priv->firmware_loading_complete); | ||
1744 | return; | 1745 | return; |
1745 | 1746 | ||
1746 | try_again: | 1747 | try_again: |
@@ -1754,6 +1755,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1754 | IWL_ERR(priv, "failed to allocate pci memory\n"); | 1755 | IWL_ERR(priv, "failed to allocate pci memory\n"); |
1755 | iwl_dealloc_ucode_pci(priv); | 1756 | iwl_dealloc_ucode_pci(priv); |
1756 | out_unbind: | 1757 | out_unbind: |
1758 | complete(&priv->firmware_loading_complete); | ||
1757 | device_release_driver(&priv->pci_dev->dev); | 1759 | device_release_driver(&priv->pci_dev->dev); |
1758 | release_firmware(ucode_raw); | 1760 | release_firmware(ucode_raw); |
1759 | } | 1761 | } |
@@ -3671,6 +3673,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3671 | iwl_power_initialize(priv); | 3673 | iwl_power_initialize(priv); |
3672 | iwl_tt_initialize(priv); | 3674 | iwl_tt_initialize(priv); |
3673 | 3675 | ||
3676 | init_completion(&priv->firmware_loading_complete); | ||
3677 | |||
3674 | err = iwl_request_firmware(priv, true); | 3678 | err = iwl_request_firmware(priv, true); |
3675 | if (err) | 3679 | if (err) |
3676 | goto out_remove_sysfs; | 3680 | goto out_remove_sysfs; |
@@ -3711,6 +3715,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3711 | if (!priv) | 3715 | if (!priv) |
3712 | return; | 3716 | return; |
3713 | 3717 | ||
3718 | wait_for_completion(&priv->firmware_loading_complete); | ||
3719 | |||
3714 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); | 3720 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); |
3715 | 3721 | ||
3716 | iwl_dbgfs_unregister(priv); | 3722 | iwl_dbgfs_unregister(priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index ef1720a852e9..4d4c6516430a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1304,6 +1304,8 @@ struct iwl_priv { | |||
1304 | struct delayed_work alive_start; | 1304 | struct delayed_work alive_start; |
1305 | struct delayed_work scan_check; | 1305 | struct delayed_work scan_check; |
1306 | 1306 | ||
1307 | struct completion firmware_loading_complete; | ||
1308 | |||
1307 | /*For 3945 only*/ | 1309 | /*For 3945 only*/ |
1308 | struct delayed_work thermal_periodic; | 1310 | struct delayed_work thermal_periodic; |
1309 | struct delayed_work rfkill_poll; | 1311 | struct delayed_work rfkill_poll; |