--- /dev/null
+
+Reason for adding to linux-next-pending/ :
+
+On Fri, Oct 01, 2010 at 05:47:53AM -0700, Christian Lamparter wrote:
+> Currently, everyone is waiting for:
+> "[PATCH 1/6] mac80211: perform scan cancel in hw reset work"
+> (hopefully, it fixes the dreaded ieee80211_hw_restart deadlock.)
+
+We need this for testing purposes for carl9170 which may
+get done this weekend.
+
+From 6b2daf7ad7067f3acc90f046700383a2c3ffad19 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Fri, 1 Oct 2010 14:05:27 +0200
+Subject: [PATCH] mac80211: perform scan cancel in hw reset work
+
+Move ieee80211_scan_cancel() and all other related code to
+ieee80211_restart_work() as ieee80211_restart_hw() is intended to be
+callable from any context.
+
+Fix a bug that RTNL lock is not taken during ieee80211_cancel_scan().
+
+Take local->mtx before WARN(test_bit(SCAN_HW_SCANNING, &local->scanning)
+to prevent the race condition with __ieee80211_start_scan() described
+here: http://marc.info/?l=linux-wireless&m=128516716810537&w=2
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+ net/mac80211/main.c | 19 ++++++++++---------
+ 1 files changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/net/mac80211/main.c b/net/mac80211/main.c
+index db341a9..ba332ef 100644
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -295,7 +295,17 @@ static void ieee80211_restart_work(struct work_struct *work)
+ struct ieee80211_local *local =
+ container_of(work, struct ieee80211_local, restart_work);
+
++ /* wait for scan work complete */
++ flush_workqueue(local->workqueue);
++
++ mutex_lock(&local->mtx);
++ WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
++ "%s called with hardware scan in progress\n", __func__);
++ mutex_unlock(&local->mtx);
++
+ rtnl_lock();
++ if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)))
++ ieee80211_scan_cancel(local);
+ ieee80211_reconfig(local);
+ rtnl_unlock();
+ }
+@@ -306,15 +316,6 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
+
+ trace_api_restart_hw(local);
+
+- /* wait for scan work complete */
+- flush_workqueue(local->workqueue);
+-
+- WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
+- "%s called with hardware scan in progress\n", __func__);
+-
+- if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)))
+- ieee80211_scan_cancel(local);
+-
+ /* use this reason, ieee80211_reconfig will unblock it */
+ ieee80211_stop_queues_by_reason(hw,
+ IEEE80211_QUEUE_STOP_REASON_SUSPEND);
+--
+1.7.0.4
+