diff options
author | Jouni Malinen <jkmaline@cc.hut.fi> | 2005-10-02 20:19:01 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-03 22:00:09 -0400 |
commit | 7cb3cd090c2725b80561958a362c2ba15a7a8c86 (patch) | |
tree | 9fc947ea92077967b3a0e6437d32130b3e9d772d | |
parent | c355184cd3cd58c9ffc78f2a17e0ac3563312ea7 (diff) |
[PATCH] hostap: Unregister netdevs before freeing local data
Unregister all netdevs before freeing local data. I was unable to
trigger any crashes without this change when running busy loops for
driver operations when ejecting a Prism2 PC Card. Anyway, should there
be a race condition with this, better make it less likely to happen by
unregistering the netdevs first.
Signed-off-by: Jouni Malinen <jkmaline@cc.hut.fi>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r-- | drivers/net/wireless/hostap/hostap_hw.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index e533a663deda..59fc15572395 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c | |||
@@ -3322,6 +3322,18 @@ static void prism2_free_local_data(struct net_device *dev) | |||
3322 | iface = netdev_priv(dev); | 3322 | iface = netdev_priv(dev); |
3323 | local = iface->local; | 3323 | local = iface->local; |
3324 | 3324 | ||
3325 | /* Unregister all netdevs before freeing local data. */ | ||
3326 | list_for_each_safe(ptr, n, &local->hostap_interfaces) { | ||
3327 | iface = list_entry(ptr, struct hostap_interface, list); | ||
3328 | if (iface->type == HOSTAP_INTERFACE_MASTER) { | ||
3329 | /* special handling for this interface below */ | ||
3330 | continue; | ||
3331 | } | ||
3332 | hostap_remove_interface(iface->dev, 0, 1); | ||
3333 | } | ||
3334 | |||
3335 | unregister_netdev(local->dev); | ||
3336 | |||
3325 | flush_scheduled_work(); | 3337 | flush_scheduled_work(); |
3326 | 3338 | ||
3327 | if (timer_pending(&local->crypt_deinit_timer)) | 3339 | if (timer_pending(&local->crypt_deinit_timer)) |
@@ -3382,15 +3394,6 @@ static void prism2_free_local_data(struct net_device *dev) | |||
3382 | prism2_download_free_data(local->dl_sec); | 3394 | prism2_download_free_data(local->dl_sec); |
3383 | #endif /* PRISM2_DOWNLOAD_SUPPORT */ | 3395 | #endif /* PRISM2_DOWNLOAD_SUPPORT */ |
3384 | 3396 | ||
3385 | list_for_each_safe(ptr, n, &local->hostap_interfaces) { | ||
3386 | iface = list_entry(ptr, struct hostap_interface, list); | ||
3387 | if (iface->type == HOSTAP_INTERFACE_MASTER) { | ||
3388 | /* special handling for this interface below */ | ||
3389 | continue; | ||
3390 | } | ||
3391 | hostap_remove_interface(iface->dev, 0, 1); | ||
3392 | } | ||
3393 | |||
3394 | prism2_clear_set_tim_queue(local); | 3397 | prism2_clear_set_tim_queue(local); |
3395 | 3398 | ||
3396 | list_for_each_safe(ptr, n, &local->bss_list) { | 3399 | list_for_each_safe(ptr, n, &local->bss_list) { |
@@ -3403,7 +3406,6 @@ static void prism2_free_local_data(struct net_device *dev) | |||
3403 | kfree(local->last_scan_results); | 3406 | kfree(local->last_scan_results); |
3404 | kfree(local->generic_elem); | 3407 | kfree(local->generic_elem); |
3405 | 3408 | ||
3406 | unregister_netdev(local->dev); | ||
3407 | free_netdev(local->dev); | 3409 | free_netdev(local->dev); |
3408 | } | 3410 | } |
3409 | 3411 | ||