libertas: wake all pending commands on shutdown
Marcelo Tosatti
mtosatti at redhat.unroutablecom
Mon Dec 11 15:18:31 EST 2006
Commit: d2bd5c5a43b8b828521b322d8adf0528fa58391d
Parent: 55cf1c4375aab7c5540078a096e9d82abea158af
commit d2bd5c5a43b8b828521b322d8adf0528fa58391d
Author: Marcelo Tosatti <mtosatti at redhat.com>
AuthorDate: Mon Dec 11 17:49:13 2006 -0200
Commit: Marcelo Tosatti <mtosatti at redhat.com>
CommitDate: Mon Dec 11 17:49:13 2006 -0200
libertas: wake all pending commands on shutdown
Wake all pending commands on driver shutdown, one of them which is not
adapter->CurCmd might hold rtnl_lock (ethtool/ioctl for example), which
will cause unregister_netdev() to deadlock.
Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
---
drivers/net/wireless/libertas/wlan_main.c | 23 ++++++++++++++++-------
1 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/libertas/wlan_main.c b/drivers/net/wireless/libertas/wlan_main.c
index 253ebe3..9b3f469 100644
--- a/drivers/net/wireless/libertas/wlan_main.c
+++ b/drivers/net/wireless/libertas/wlan_main.c
@@ -1074,6 +1074,20 @@ err_kmalloc:
return NULL;
}
+void wake_pending_cmdnodes(wlan_private *priv)
+{
+ struct CmdCtrlNode *cmdnode;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->adapter->driver_lock, flags);
+ list_for_each_entry(cmdnode, &priv->adapter->CmdPendingQ, list) {
+ cmdnode->CmdWaitQWoken = 1;
+ wake_up_interruptible(&cmdnode->cmdwait_q);
+ }
+ spin_unlock_irqrestore(&priv->adapter->driver_lock, flags);
+}
+
+
/**
* @brief This function removes the card.
*
@@ -1108,19 +1122,14 @@ static int wlan_remove_card(void *card)
netif_stop_queue(priv->wlan_dev.netdev);
netif_carrier_off(priv->wlan_dev.netdev);
+ wake_pending_cmdnodes(priv);
+
unregister_netdev(mesh_dev);
unregister_netdev(dev);
cancel_delayed_work(&priv->assoc_work);
destroy_workqueue(priv->assoc_thread);
- if (Adapter->CurCmd) {
- dprintk(1, "Wake up current cmdwait_q\n");
- wake_up_interruptible(&Adapter->CurCmd->cmdwait_q);
- }
-
- Adapter->CurCmd = NULL;
-
if (Adapter->PSMode == Wlan802_11PowerModeMAX_PSP) {
Adapter->PSMode = Wlan802_11PowerModeCAM;
libertas_ps_wakeup(priv, HostCmd_OPTION_WAITFORRSP);
More information about the Commits-kernel
mailing list