diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-04-13 06:14:49 -0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-04-22 13:03:03 -0400 |
commit | e74fe2330a5a721610b2b69652d2ec2ebbd302e0 (patch) | |
tree | 6278e09720a76776b69f8277057b41e3858ffebb /drivers | |
parent | a8674a1efca60d863d4caa47e102cc4d70d5ff9b (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.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 2 |
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 | ||
870 | static 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 | |||
870 | void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | 883 | void 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 | ||
1116 | enum iwl_rxon_context_id { | 1116 | enum iwl_rxon_context_id { |