[PATCH] libertas: terminate scan when stopping interface
Sven Neumann
s.neumann at raumfeld.com
Mon Nov 15 08:12:21 EST 2010
We have successfully tested this patch on Linux 2.6.36 on an ARM device
using an 8686 chip connected over SDIO. It fixes a crash that we have
been observing occasionally during suspend/resume.
On Sun, 2010-10-31 at 17:47 +0000, Daniel Drake wrote:
> There are currently no provisions in place to ensure that the scanning
> task has been stopped when the interface is stopped or removed.
>
> This can result in a WARNING at net/wireless/core.c:643 and other badness
> when you remove the module while a scan is happening.
>
> Terminate the scanning task during interface stop.
>
> Signed-off-by: Daniel Drake <dsd at laptop.org>
> ---
> drivers/net/wireless/libertas/cfg.c | 5 +++--
> drivers/net/wireless/libertas/dev.h | 1 +
> drivers/net/wireless/libertas/main.c | 7 +++++++
> 3 files changed, 11 insertions(+), 2 deletions(-)
Tested-by: Sven Neumann <s.neumann at raumfeld.com>
> diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
> index 5046a00..373930a 100644
> --- a/drivers/net/wireless/libertas/cfg.c
> +++ b/drivers/net/wireless/libertas/cfg.c
> @@ -700,8 +700,9 @@ static void lbs_scan_worker(struct work_struct *work)
>
> if (priv->scan_channel < priv->scan_req->n_channels) {
> cancel_delayed_work(&priv->scan_work);
> - queue_delayed_work(priv->work_thread, &priv->scan_work,
> - msecs_to_jiffies(300));
> + if (!priv->stopping)
> + queue_delayed_work(priv->work_thread, &priv->scan_work,
> + msecs_to_jiffies(300));
> }
>
> /* This is the final data we are about to send */
> diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
> index f062ed5..cb14c38 100644
> --- a/drivers/net/wireless/libertas/dev.h
> +++ b/drivers/net/wireless/libertas/dev.h
> @@ -36,6 +36,7 @@ struct lbs_private {
> /* CFG80211 */
> struct wireless_dev *wdev;
> bool wiphy_registered;
> + bool stopping;
> struct cfg80211_scan_request *scan_req;
> u8 assoc_bss[ETH_ALEN];
> u8 disassoc_reason;
> diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
> index 47ce5a6..46b88b1 100644
> --- a/drivers/net/wireless/libertas/main.c
> +++ b/drivers/net/wireless/libertas/main.c
> @@ -104,6 +104,7 @@ static int lbs_dev_open(struct net_device *dev)
> lbs_deb_enter(LBS_DEB_NET);
>
> spin_lock_irq(&priv->driver_lock);
> + priv->stopping = false;
>
> if (priv->connect_status == LBS_CONNECTED)
> netif_carrier_on(dev);
> @@ -131,10 +132,16 @@ static int lbs_eth_stop(struct net_device *dev)
> lbs_deb_enter(LBS_DEB_NET);
>
> spin_lock_irq(&priv->driver_lock);
> + priv->stopping = true;
> netif_stop_queue(dev);
> spin_unlock_irq(&priv->driver_lock);
>
> schedule_work(&priv->mcast_work);
> + cancel_delayed_work_sync(&priv->scan_work);
> + if (priv->scan_req) {
> + cfg80211_scan_done(priv->scan_req, false);
> + priv->scan_req = NULL;
> + }
>
> lbs_deb_leave(LBS_DEB_NET);
> return 0;
More information about the libertas-dev
mailing list