diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/wmi.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/wmi.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index f2ff18cf3e60..dc6c6fc2e095 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c | |||
@@ -101,6 +101,7 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv) | |||
101 | wmi->drv_priv = priv; | 101 | wmi->drv_priv = priv; |
102 | wmi->stopped = false; | 102 | wmi->stopped = false; |
103 | mutex_init(&wmi->op_mutex); | 103 | mutex_init(&wmi->op_mutex); |
104 | mutex_init(&wmi->multi_write_mutex); | ||
104 | init_completion(&wmi->cmd_wait); | 105 | init_completion(&wmi->cmd_wait); |
105 | 106 | ||
106 | return wmi; | 107 | return wmi; |
@@ -128,7 +129,7 @@ void ath9k_wmi_tasklet(unsigned long data) | |||
128 | void *wmi_event; | 129 | void *wmi_event; |
129 | unsigned long flags; | 130 | unsigned long flags; |
130 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | 131 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS |
131 | u32 txrate; | 132 | __be32 txrate; |
132 | #endif | 133 | #endif |
133 | 134 | ||
134 | spin_lock_irqsave(&priv->wmi->wmi_lock, flags); | 135 | spin_lock_irqsave(&priv->wmi->wmi_lock, flags); |
@@ -203,6 +204,14 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, | |||
203 | return; | 204 | return; |
204 | } | 205 | } |
205 | 206 | ||
207 | /* Check if there has been a timeout. */ | ||
208 | spin_lock(&wmi->wmi_lock); | ||
209 | if (cmd_id != wmi->last_cmd_id) { | ||
210 | spin_unlock(&wmi->wmi_lock); | ||
211 | goto free_skb; | ||
212 | } | ||
213 | spin_unlock(&wmi->wmi_lock); | ||
214 | |||
206 | /* WMI command response */ | 215 | /* WMI command response */ |
207 | ath9k_wmi_rsp_callback(wmi, skb); | 216 | ath9k_wmi_rsp_callback(wmi, skb); |
208 | 217 | ||
@@ -265,6 +274,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | |||
265 | struct sk_buff *skb; | 274 | struct sk_buff *skb; |
266 | u8 *data; | 275 | u8 *data; |
267 | int time_left, ret = 0; | 276 | int time_left, ret = 0; |
277 | unsigned long flags; | ||
268 | 278 | ||
269 | if (!wmi) | 279 | if (!wmi) |
270 | return -EINVAL; | 280 | return -EINVAL; |
@@ -296,6 +306,10 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | |||
296 | if (ret) | 306 | if (ret) |
297 | goto out; | 307 | goto out; |
298 | 308 | ||
309 | spin_lock_irqsave(&wmi->wmi_lock, flags); | ||
310 | wmi->last_cmd_id = cmd_id; | ||
311 | spin_unlock_irqrestore(&wmi->wmi_lock, flags); | ||
312 | |||
299 | time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout); | 313 | time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout); |
300 | if (!time_left) { | 314 | if (!time_left) { |
301 | ath_print(common, ATH_DBG_WMI, | 315 | ath_print(common, ATH_DBG_WMI, |