summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/init.c
diff options
context:
space:
mode:
authorAmitkumar Karwar2013-05-18 02:50:19 +0200
committerJohn W. Linville2013-05-22 21:08:47 +0200
commit06041118ef0908b9cae7657a7b734699bcf61a6c (patch)
treef6b74fb5f394c2997a94793318fa18efa7e2b069 /drivers/net/wireless/mwifiex/init.c
parentmwifiex: rename mwifiex_free_adapter() routine in init.c (diff)
downloadkernel-qcow2-linux-06041118ef0908b9cae7657a7b734699bcf61a6c.tar.gz
kernel-qcow2-linux-06041118ef0908b9cae7657a7b734699bcf61a6c.tar.xz
kernel-qcow2-linux-06041118ef0908b9cae7657a7b734699bcf61a6c.zip
mwifiex: scan delay timer cleanup in unload path
Return from scan delay timer routine if surprise_removed flag is true. Also, cancel the timer in unload path. This fixes a crash when scan delay timer accesses structures that have been freed already. Tested with "iwlist mlan0 scan & sleep 1; rmmod mwifiex_sdio" Reported-by: Daniel Drake <dsd@laptop.org> Tested-by: Daniel Drake <dsd@laptop.org> 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/init.c')
-rw-r--r--drivers/net/wireless/mwifiex/init.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 58e151edfa09..71bbf1204685 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -59,6 +59,9 @@ static void scan_delay_timer_fn(unsigned long data)
struct cmd_ctrl_node *cmd_node, *tmp_node;
unsigned long flags;
+ if (adapter->surprise_removed)
+ return;
+
if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
/*
* Abort scan operation by cancelling all pending scan
@@ -458,11 +461,18 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
static void
mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
{
+ int i;
+
if (!adapter) {
pr_err("%s: adapter is NULL\n", __func__);
return;
}
+ for (i = 0; i < adapter->priv_num; i++) {
+ if (adapter->priv[i])
+ del_timer_sync(&adapter->priv[i]->scan_delay_timer);
+ }
+
mwifiex_cancel_all_pending_cmd(adapter);
/* Free lock variables */