diff options
author | Ben Greear <greearb@candelatech.com> | 2010-09-27 12:07:26 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-10-05 13:35:21 -0400 |
commit | 5a254ffe3ffdfa84fe076009bd8e88da412180d2 (patch) | |
tree | 31e2263807b442d507d98d7d5b1c53bf0b0702c2 /net/wireless/core.c | |
parent | b1a9338d5eaa9c38c326e20ce339247f4d585b62 (diff) |
wireless: Use first phyX name available when registering phy devices.
Choose first available phyX name when creating phy devices. This
means that reloading a wifi driver will not cause a change in the
name of it's phy device.
Also, allow users to rename a phy to any un-used name, including
phy%d.
Signed-off-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless/core.c')
-rw-r--r-- | net/wireless/core.c | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c index 9c21ebf9780e..1684ad91763c 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -178,26 +178,10 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
178 | char *newname) | 178 | char *newname) |
179 | { | 179 | { |
180 | struct cfg80211_registered_device *rdev2; | 180 | struct cfg80211_registered_device *rdev2; |
181 | int wiphy_idx, taken = -1, result, digits; | 181 | int result; |
182 | 182 | ||
183 | assert_cfg80211_lock(); | 183 | assert_cfg80211_lock(); |
184 | 184 | ||
185 | /* prohibit calling the thing phy%d when %d is not its number */ | ||
186 | sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); | ||
187 | if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) { | ||
188 | /* count number of places needed to print wiphy_idx */ | ||
189 | digits = 1; | ||
190 | while (wiphy_idx /= 10) | ||
191 | digits++; | ||
192 | /* | ||
193 | * deny the name if it is phy<idx> where <idx> is printed | ||
194 | * without leading zeroes. taken == strlen(newname) here | ||
195 | */ | ||
196 | if (taken == strlen(PHY_NAME) + digits) | ||
197 | return -EINVAL; | ||
198 | } | ||
199 | |||
200 | |||
201 | /* Ignore nop renames */ | 185 | /* Ignore nop renames */ |
202 | if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) | 186 | if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) |
203 | return 0; | 187 | return 0; |
@@ -205,7 +189,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
205 | /* Ensure another device does not already have this name. */ | 189 | /* Ensure another device does not already have this name. */ |
206 | list_for_each_entry(rdev2, &cfg80211_rdev_list, list) | 190 | list_for_each_entry(rdev2, &cfg80211_rdev_list, list) |
207 | if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) | 191 | if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) |
208 | return -EINVAL; | 192 | return -EEXIST; |
209 | 193 | ||
210 | result = device_rename(&rdev->wiphy.dev, newname); | 194 | result = device_rename(&rdev->wiphy.dev, newname); |
211 | if (result) | 195 | if (result) |
@@ -320,9 +304,11 @@ static void cfg80211_event_work(struct work_struct *work) | |||
320 | struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | 304 | struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) |
321 | { | 305 | { |
322 | static int wiphy_counter; | 306 | static int wiphy_counter; |
323 | 307 | int i; | |
324 | struct cfg80211_registered_device *rdev; | 308 | struct cfg80211_registered_device *rdev, *rdev2; |
325 | int alloc_size; | 309 | int alloc_size; |
310 | char nname[IFNAMSIZ + 1]; | ||
311 | bool found = false; | ||
326 | 312 | ||
327 | WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key)); | 313 | WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key)); |
328 | WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc)); | 314 | WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc)); |
@@ -346,16 +332,36 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
346 | 332 | ||
347 | if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) { | 333 | if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) { |
348 | wiphy_counter--; | 334 | wiphy_counter--; |
335 | goto too_many_devs; | ||
336 | } | ||
337 | |||
338 | /* 64k wiphy devices is enough for anyone! */ | ||
339 | for (i = 0; i < 0xFFFF; i++) { | ||
340 | found = false; | ||
341 | snprintf(nname, sizeof(nname)-1, PHY_NAME "%d", i); | ||
342 | nname[sizeof(nname)-1] = 0; | ||
343 | list_for_each_entry(rdev2, &cfg80211_rdev_list, list) | ||
344 | if (strcmp(nname, dev_name(&rdev2->wiphy.dev)) == 0) { | ||
345 | found = true; | ||
346 | break; | ||
347 | } | ||
348 | |||
349 | if (!found) | ||
350 | break; | ||
351 | } | ||
352 | |||
353 | if (unlikely(found)) { | ||
354 | too_many_devs: | ||
349 | mutex_unlock(&cfg80211_mutex); | 355 | mutex_unlock(&cfg80211_mutex); |
350 | /* ugh, wrapped! */ | 356 | /* ugh, too many devices already! */ |
351 | kfree(rdev); | 357 | kfree(rdev); |
352 | return NULL; | 358 | return NULL; |
353 | } | 359 | } |
354 | 360 | ||
355 | mutex_unlock(&cfg80211_mutex); | ||
356 | |||
357 | /* give it a proper name */ | 361 | /* give it a proper name */ |
358 | dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); | 362 | dev_set_name(&rdev->wiphy.dev, "%s", nname); |
363 | |||
364 | mutex_unlock(&cfg80211_mutex); | ||
359 | 365 | ||
360 | mutex_init(&rdev->mtx); | 366 | mutex_init(&rdev->mtx); |
361 | mutex_init(&rdev->devlist_mtx); | 367 | mutex_init(&rdev->devlist_mtx); |