aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/wireless/core.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 24a21add0ba6..7eabd55417a5 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -91,7 +91,6 @@ int wiphy_register(struct wiphy *wiphy)
91 91
92 mutex_lock(&cfg80211_drv_mutex); 92 mutex_lock(&cfg80211_drv_mutex);
93 93
94
95 res = device_add(&drv->wiphy.dev); 94 res = device_add(&drv->wiphy.dev);
96 if (res) 95 if (res)
97 goto out_unlock; 96 goto out_unlock;
@@ -114,14 +113,26 @@ void wiphy_unregister(struct wiphy *wiphy)
114{ 113{
115 struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy); 114 struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
116 115
116 /* protect the device list */
117 mutex_lock(&cfg80211_drv_mutex); 117 mutex_lock(&cfg80211_drv_mutex);
118 118
119 /* hold registered driver mutex during list removal as well 119 BUG_ON(!list_empty(&drv->netdev_list));
120 * to make sure no commands are in progress at the moment */ 120
121 /*
122 * Try to grab drv->mtx. If a command is still in progress,
123 * hopefully the driver will refuse it since it's tearing
124 * down the device already. We wait for this command to complete
125 * before unlinking the item from the list.
126 * Note: as codified by the BUG_ON above we cannot get here if
127 * a virtual interface is still associated. Hence, we can only
128 * get to lock contention here if userspace issues a command
129 * that identified the hardware by wiphy index.
130 */
121 mutex_lock(&drv->mtx); 131 mutex_lock(&drv->mtx);
122 list_del(&drv->list); 132 /* unlock again before freeing */
123 mutex_unlock(&drv->mtx); 133 mutex_unlock(&drv->mtx);
124 134
135 list_del(&drv->list);
125 device_del(&drv->wiphy.dev); 136 device_del(&drv->wiphy.dev);
126 debugfs_remove(drv->wiphy.debugfsdir); 137 debugfs_remove(drv->wiphy.debugfsdir);
127 138