aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-04-29 10:41:53 -0400
committerReinette Chatre <reinette.chatre@intel.com>2010-05-10 17:56:14 -0400
commit562db532760827f6ce30801a08e6b568848bc9f2 (patch)
tree42c3995c06d7bd7837db4d4862387fa1f72fd2aa
parent79733a865c7fd778ce45e3503962b3a875b0a153 (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.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h2
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;