}
 
 /* requires cfg80211_mutex to be held! */
-static struct cfg80211_registered_device *
+struct cfg80211_registered_device *
 __cfg80211_drv_from_info(struct genl_info *info)
 {
        int ifindex;
        mutex_unlock(&drv->mtx);
 }
 
+/* requires cfg80211_mutex to be held */
 int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
                        char *newname)
 {
        struct cfg80211_registered_device *drv;
        int wiphy_idx, taken = -1, result, digits;
 
-       mutex_lock(&cfg80211_mutex);
+       assert_cfg80211_lock();
 
        /* prohibit calling the thing phy%d when %d is not its number */
        sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
                 * deny the name if it is phy<idx> where <idx> is printed
                 * without leading zeroes. taken == strlen(newname) here
                 */
-               result = -EINVAL;
                if (taken == strlen(PHY_NAME) + digits)
-                       goto out_unlock;
+                       return -EINVAL;
        }
 
 
        /* Ignore nop renames */
-       result = 0;
        if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
-               goto out_unlock;
+               return 0;
 
        /* Ensure another device does not already have this name. */
-       list_for_each_entry(drv, &cfg80211_drv_list, list) {
-               result = -EINVAL;
+       list_for_each_entry(drv, &cfg80211_drv_list, list)
                if (strcmp(newname, dev_name(&drv->wiphy.dev)) == 0)
-                       goto out_unlock;
-       }
+                       return -EINVAL;
 
-       /* this will only check for collisions in sysfs
-        * which is not even always compiled in.
-        */
        result = device_rename(&rdev->wiphy.dev, newname);
        if (result)
-               goto out_unlock;
+               return result;
 
        if (rdev->wiphy.debugfsdir &&
            !debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
                printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n",
                       newname);
 
-       result = 0;
-out_unlock:
-       mutex_unlock(&cfg80211_mutex);
-       if (result == 0)
-               nl80211_notify_dev_rename(rdev);
+       nl80211_notify_dev_rename(rdev);
 
-       return result;
+       return 0;
 }
 
 /* exported functions */
 
        int result = 0, rem_txq_params = 0;
        struct nlattr *nl_txq_params;
 
-       rdev = cfg80211_get_dev_from_info(info);
-       if (IS_ERR(rdev))
-               return PTR_ERR(rdev);
+       rtnl_lock();
+
+       mutex_lock(&cfg80211_mutex);
+
+       rdev = __cfg80211_drv_from_info(info);
+       if (IS_ERR(rdev)) {
+               result = PTR_ERR(rdev);
+               goto unlock;
+       }
 
-       if (info->attrs[NL80211_ATTR_WIPHY_NAME]) {
+       mutex_lock(&rdev->mtx);
+
+       if (info->attrs[NL80211_ATTR_WIPHY_NAME])
                result = cfg80211_dev_rename(
                        rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
-               if (result)
-                       goto bad_res;
-       }
+
+       mutex_unlock(&cfg80211_mutex);
+
+       if (result)
+               goto bad_res;
 
        if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
                struct ieee80211_txq_params txq_params;
 
 
  bad_res:
-       cfg80211_put_dev(rdev);
+       mutex_unlock(&rdev->mtx);
+ unlock:
+       rtnl_unlock();
        return result;
 }