Commit e74fe233 authored by Johannes Berg's avatar Johannes Berg Committed by Wey-Yi Guy

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: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent a8674a1e
...@@ -2266,6 +2266,7 @@ void iwlagn_init_notification_wait(struct iwl_priv *priv, ...@@ -2266,6 +2266,7 @@ void iwlagn_init_notification_wait(struct iwl_priv *priv,
wait_entry->fn_data = fn_data; wait_entry->fn_data = fn_data;
wait_entry->cmd = cmd; wait_entry->cmd = cmd;
wait_entry->triggered = false; wait_entry->triggered = false;
wait_entry->aborted = false;
spin_lock_bh(&priv->_agn.notif_wait_lock); spin_lock_bh(&priv->_agn.notif_wait_lock);
list_add(&wait_entry->list, &priv->_agn.notif_waits); list_add(&wait_entry->list, &priv->_agn.notif_waits);
...@@ -2279,13 +2280,16 @@ int iwlagn_wait_notification(struct iwl_priv *priv, ...@@ -2279,13 +2280,16 @@ int iwlagn_wait_notification(struct iwl_priv *priv,
int ret; int ret;
ret = wait_event_timeout(priv->_agn.notif_waitq, ret = wait_event_timeout(priv->_agn.notif_waitq,
wait_entry->triggered, wait_entry->triggered || wait_entry->aborted,
timeout); timeout);
spin_lock_bh(&priv->_agn.notif_wait_lock); spin_lock_bh(&priv->_agn.notif_wait_lock);
list_del(&wait_entry->list); list_del(&wait_entry->list);
spin_unlock_bh(&priv->_agn.notif_wait_lock); spin_unlock_bh(&priv->_agn.notif_wait_lock);
if (wait_entry->aborted)
return -EIO;
/* return value is always >= 0 */ /* return value is always >= 0 */
if (ret <= 0) if (ret <= 0)
return -ETIMEDOUT; return -ETIMEDOUT;
......
...@@ -867,6 +867,19 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv, ...@@ -867,6 +867,19 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv,
} }
#endif #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) void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
{ {
unsigned int reload_msec; unsigned int reload_msec;
...@@ -878,6 +891,8 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) ...@@ -878,6 +891,8 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
/* Cancel currently queued command. */ /* Cancel currently queued command. */
clear_bit(STATUS_HCMD_ACTIVE, &priv->status); clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
iwlagn_abort_notification_waits(priv);
/* Keep the restart process from trying to send host /* Keep the restart process from trying to send host
* commands by clearing the ready bit */ * commands by clearing the ready bit */
clear_bit(STATUS_READY, &priv->status); clear_bit(STATUS_READY, &priv->status);
......
...@@ -1110,7 +1110,7 @@ struct iwl_notification_wait { ...@@ -1110,7 +1110,7 @@ struct iwl_notification_wait {
void *fn_data; void *fn_data;
u8 cmd; u8 cmd;
bool triggered; bool triggered, aborted;
}; };
enum iwl_rxon_context_id { enum iwl_rxon_context_id {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment