aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-04-13 06:14:49 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2011-04-22 13:03:03 -0400
commite74fe2330a5a721610b2b69652d2ec2ebbd302e0 (patch)
tree6278e09720a76776b69f8277057b41e3858ffebb /drivers
parenta8674a1efca60d863d4caa47e102cc4d70d5ff9b (diff)
iwlagn: leave notification waits on firmware errors
When the firmware encounters an error while the driver is waiting for a notification, it will never get that notification. Therefore, instead of timing out, bail out on errors when waiting for notifications. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h2
3 files changed, 21 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 828416881d6f..a29e2e267ee4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -2266,6 +2266,7 @@ void iwlagn_init_notification_wait(struct iwl_priv *priv,
2266 wait_entry->fn_data = fn_data; 2266 wait_entry->fn_data = fn_data;
2267 wait_entry->cmd = cmd; 2267 wait_entry->cmd = cmd;
2268 wait_entry->triggered = false; 2268 wait_entry->triggered = false;
2269 wait_entry->aborted = false;
2269 2270
2270 spin_lock_bh(&priv->_agn.notif_wait_lock); 2271 spin_lock_bh(&priv->_agn.notif_wait_lock);
2271 list_add(&wait_entry->list, &priv->_agn.notif_waits); 2272 list_add(&wait_entry->list, &priv->_agn.notif_waits);
@@ -2279,13 +2280,16 @@ int iwlagn_wait_notification(struct iwl_priv *priv,
2279 int ret; 2280 int ret;
2280 2281
2281 ret = wait_event_timeout(priv->_agn.notif_waitq, 2282 ret = wait_event_timeout(priv->_agn.notif_waitq,
2282 wait_entry->triggered, 2283 wait_entry->triggered || wait_entry->aborted,
2283 timeout); 2284 timeout);
2284 2285
2285 spin_lock_bh(&priv->_agn.notif_wait_lock); 2286 spin_lock_bh(&priv->_agn.notif_wait_lock);
2286 list_del(&wait_entry->list); 2287 list_del(&wait_entry->list);
2287 spin_unlock_bh(&priv->_agn.notif_wait_lock); 2288 spin_unlock_bh(&priv->_agn.notif_wait_lock);
2288 2289
2290 if (wait_entry->aborted)
2291 return -EIO;
2292
2289 /* return value is always >= 0 */ 2293 /* return value is always >= 0 */
2290 if (ret <= 0) 2294 if (ret <= 0)
2291 return -ETIMEDOUT; 2295 return -ETIMEDOUT;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 885167f8168d..46d69657407c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -867,6 +867,19 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv,
867} 867}
868#endif 868#endif
869 869
870static void iwlagn_abort_notification_waits(struct iwl_priv *priv)
871{
872 unsigned long flags;
873 struct iwl_notification_wait *wait_entry;
874
875 spin_lock_irqsave(&priv->_agn.notif_wait_lock, flags);
876 list_for_each_entry(wait_entry, &priv->_agn.notif_waits, list)
877 wait_entry->aborted = true;
878 spin_unlock_irqrestore(&priv->_agn.notif_wait_lock, flags);
879
880 wake_up_all(&priv->_agn.notif_waitq);
881}
882
870void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) 883void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
871{ 884{
872 unsigned int reload_msec; 885 unsigned int reload_msec;
@@ -878,6 +891,8 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
878 /* Cancel currently queued command. */ 891 /* Cancel currently queued command. */
879 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 892 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
880 893
894 iwlagn_abort_notification_waits(priv);
895
881 /* Keep the restart process from trying to send host 896 /* Keep the restart process from trying to send host
882 * commands by clearing the ready bit */ 897 * commands by clearing the ready bit */
883 clear_bit(STATUS_READY, &priv->status); 898 clear_bit(STATUS_READY, &priv->status);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index d8bf11727aac..03452925bae3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1110,7 +1110,7 @@ struct iwl_notification_wait {
1110 void *fn_data; 1110 void *fn_data;
1111 1111
1112 u8 cmd; 1112 u8 cmd;
1113 bool triggered; 1113 bool triggered, aborted;
1114}; 1114};
1115 1115
1116enum iwl_rxon_context_id { 1116enum iwl_rxon_context_id {