diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-04-13 03:14:49 -0700 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-04-22 10:03:03 -0700 |
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, wait_entry->fn_data = fn_data; wait_entry->cmd = cmd; wait_entry->triggered = false; + wait_entry->aborted = false; spin_lock_bh(&priv->_agn.notif_wait_lock); list_add(&wait_entry->list, &priv->_agn.notif_waits); @@ -2279,13 +2280,16 @@ int iwlagn_wait_notification(struct iwl_priv *priv, int ret; ret = wait_event_timeout(priv->_agn.notif_waitq, - wait_entry->triggered, + wait_entry->triggered || wait_entry->aborted, timeout); spin_lock_bh(&priv->_agn.notif_wait_lock); list_del(&wait_entry->list); spin_unlock_bh(&priv->_agn.notif_wait_lock); + if (wait_entry->aborted) + return -EIO; + /* return value is always >= 0 */ if (ret <= 0) 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, } #endif +static void iwlagn_abort_notification_waits(struct iwl_priv *priv) +{ + unsigned long flags; + struct iwl_notification_wait *wait_entry; + + spin_lock_irqsave(&priv->_agn.notif_wait_lock, flags); + list_for_each_entry(wait_entry, &priv->_agn.notif_waits, list) + wait_entry->aborted = true; + spin_unlock_irqrestore(&priv->_agn.notif_wait_lock, flags); + + wake_up_all(&priv->_agn.notif_waitq); +} + void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) { unsigned int reload_msec; @@ -878,6 +891,8 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) /* Cancel currently queued command. */ clear_bit(STATUS_HCMD_ACTIVE, &priv->status); + iwlagn_abort_notification_waits(priv); + /* Keep the restart process from trying to send host * commands by clearing the ready bit */ 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 { void *fn_data; u8 cmd; - bool triggered; + bool triggered, aborted; }; enum iwl_rxon_context_id { |