diff options
| -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 | ||
