diff options
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/core.c | 19 |
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 | ||