diff options
author | Amitkumar Karwar <akarwar@marvell.com> | 2014-02-27 19:35:15 -0800 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-02-28 14:33:41 -0500 |
commit | 4af2bd49e6777d39db9bafc868860f0cfdd04652 (patch) | |
tree | 1aba93358be2baa1881d597b63eef6252634aaf6 /drivers/net/wireless/mwifiex | |
parent | 828cf2222f05a22e51cdde4fb959d256bf31613b (diff) |
mwifiex: abort scan while cancelling pending command
mwifiex_cancel_pending_ioctl() and
mwifiex_cancel_all_pending_cmd() are called in command timeout
and driver unload paths respectively.
If scan operation is in progress, we should abort it smoothly.
Reported-by: Tim Shepard <shep@alum.mit.edu>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r-- | drivers/net/wireless/mwifiex/cmdevt.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 64e708b79f0e..58cf3a98f1f7 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -966,7 +966,9 @@ void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) { struct cmd_ctrl_node *cmd_node = NULL, *tmp_node; - unsigned long flags; + unsigned long flags, cmd_flags; + struct mwifiex_private *priv; + int i; /* Cancel current cmd */ if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { @@ -1006,9 +1008,21 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) } spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); - spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); - adapter->scan_processing = false; - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + if (adapter->scan_processing) { + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); + adapter->scan_processing = false; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); + for (i = 0; i < adapter->priv_num; i++) { + priv = adapter->priv[i]; + if (!priv) + continue; + if (priv->scan_request) { + dev_dbg(adapter->dev, "info: aborting scan\n"); + cfg80211_scan_done(priv->scan_request, 1); + priv->scan_request = NULL; + } + } + } } /* @@ -1027,7 +1041,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; unsigned long cmd_flags; unsigned long scan_pending_q_flags; - bool cancel_scan_cmd = false; + struct mwifiex_private *priv; + int i; if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { @@ -1053,15 +1068,24 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) mwifiex_insert_cmd_to_free_q(adapter, cmd_node); spin_lock_irqsave(&adapter->scan_pending_q_lock, scan_pending_q_flags); - cancel_scan_cmd = true; } spin_unlock_irqrestore(&adapter->scan_pending_q_lock, scan_pending_q_flags); - if (cancel_scan_cmd) { + if (adapter->scan_processing) { spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); adapter->scan_processing = false; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); + for (i = 0; i < adapter->priv_num; i++) { + priv = adapter->priv[i]; + if (!priv) + continue; + if (priv->scan_request) { + dev_dbg(adapter->dev, "info: aborting scan\n"); + cfg80211_scan_done(priv->scan_request, 1); + priv->scan_request = NULL; + } + } } adapter->cmd_wait_q.status = -1; } |