aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2011-01-25 08:15:12 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-01-27 16:41:10 -0500
commitea888357ec005abffb95acee2e61aac68dff429c (patch)
tree45e343b19e249bff3a367a729a4b69df9703995c /drivers
parent203043f579ece44bb30291442cd56332651dd37d (diff)
ath9k_htc: fix race conditions when stop device
We do not kill any scheduled tasklets when stopping device, that may cause usage of resources after free. Disable interrupts, kill tasklets and then works in correct order. Cc: stable@kernel.org Tested-by: Sujith <m.sujith@gmail.com> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c21
2 files changed, 15 insertions, 9 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 38433f9bfe59..0352f0994caa 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -142,9 +142,6 @@ static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
142{ 142{
143 ath9k_htc_exit_debug(priv->ah); 143 ath9k_htc_exit_debug(priv->ah);
144 ath9k_hw_deinit(priv->ah); 144 ath9k_hw_deinit(priv->ah);
145 tasklet_kill(&priv->swba_tasklet);
146 tasklet_kill(&priv->rx_tasklet);
147 tasklet_kill(&priv->tx_tasklet);
148 kfree(priv->ah); 145 kfree(priv->ah);
149 priv->ah = NULL; 146 priv->ah = NULL;
150} 147}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index f4d576bc3ccd..6bb59958f71e 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1025,12 +1025,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1025 int ret = 0; 1025 int ret = 0;
1026 u8 cmd_rsp; 1026 u8 cmd_rsp;
1027 1027
1028 /* Cancel all the running timers/work .. */
1029 cancel_work_sync(&priv->fatal_work);
1030 cancel_work_sync(&priv->ps_work);
1031 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1032 ath9k_led_stop_brightness(priv);
1033
1034 mutex_lock(&priv->mutex); 1028 mutex_lock(&priv->mutex);
1035 1029
1036 if (priv->op_flags & OP_INVALID) { 1030 if (priv->op_flags & OP_INVALID) {
@@ -1044,8 +1038,23 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1044 WMI_CMD(WMI_DISABLE_INTR_CMDID); 1038 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1045 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); 1039 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1046 WMI_CMD(WMI_STOP_RECV_CMDID); 1040 WMI_CMD(WMI_STOP_RECV_CMDID);
1041
1042 tasklet_kill(&priv->swba_tasklet);
1043 tasklet_kill(&priv->rx_tasklet);
1044 tasklet_kill(&priv->tx_tasklet);
1045
1047 skb_queue_purge(&priv->tx_queue); 1046 skb_queue_purge(&priv->tx_queue);
1048 1047
1048 mutex_unlock(&priv->mutex);
1049
1050 /* Cancel all the running timers/work .. */
1051 cancel_work_sync(&priv->fatal_work);
1052 cancel_work_sync(&priv->ps_work);
1053 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1054 ath9k_led_stop_brightness(priv);
1055
1056 mutex_lock(&priv->mutex);
1057
1049 /* Remove monitor interface here */ 1058 /* Remove monitor interface here */
1050 if (ah->opmode == NL80211_IFTYPE_MONITOR) { 1059 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
1051 if (ath9k_htc_remove_monitor_interface(priv)) 1060 if (ath9k_htc_remove_monitor_interface(priv))