diff options
Diffstat (limited to 'net/ieee80211/ieee80211_crypt.c')
-rw-r--r-- | net/ieee80211/ieee80211_crypt.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c index 0c366299db0f..60d3166facce 100644 --- a/net/ieee80211/ieee80211_crypt.c +++ b/net/ieee80211/ieee80211_crypt.c | |||
@@ -44,6 +44,10 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) | |||
44 | unsigned long flags; | 44 | unsigned long flags; |
45 | 45 | ||
46 | spin_lock_irqsave(&ieee->lock, flags); | 46 | spin_lock_irqsave(&ieee->lock, flags); |
47 | |||
48 | if (list_empty(&ieee->crypt_deinit_list)) | ||
49 | goto unlock; | ||
50 | |||
47 | for (ptr = ieee->crypt_deinit_list.next, n = ptr->next; | 51 | for (ptr = ieee->crypt_deinit_list.next, n = ptr->next; |
48 | ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) { | 52 | ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) { |
49 | entry = list_entry(ptr, struct ieee80211_crypt_data, list); | 53 | entry = list_entry(ptr, struct ieee80211_crypt_data, list); |
@@ -59,21 +63,35 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) | |||
59 | } | 63 | } |
60 | kfree(entry); | 64 | kfree(entry); |
61 | } | 65 | } |
66 | unlock: | ||
67 | spin_unlock_irqrestore(&ieee->lock, flags); | ||
68 | } | ||
69 | |||
70 | /* After this, crypt_deinit_list won't accept new members */ | ||
71 | void ieee80211_crypt_quiescing(struct ieee80211_device *ieee) | ||
72 | { | ||
73 | unsigned long flags; | ||
74 | |||
75 | spin_lock_irqsave(&ieee->lock, flags); | ||
76 | ieee->crypt_quiesced = 1; | ||
62 | spin_unlock_irqrestore(&ieee->lock, flags); | 77 | spin_unlock_irqrestore(&ieee->lock, flags); |
63 | } | 78 | } |
64 | 79 | ||
65 | void ieee80211_crypt_deinit_handler(unsigned long data) | 80 | void ieee80211_crypt_deinit_handler(unsigned long data) |
66 | { | 81 | { |
67 | struct ieee80211_device *ieee = (struct ieee80211_device *)data; | 82 | struct ieee80211_device *ieee = (struct ieee80211_device *)data; |
83 | unsigned long flags; | ||
68 | 84 | ||
69 | ieee80211_crypt_deinit_entries(ieee, 0); | 85 | ieee80211_crypt_deinit_entries(ieee, 0); |
70 | if (!list_empty(&ieee->crypt_deinit_list)) { | 86 | |
87 | spin_lock_irqsave(&ieee->lock, flags); | ||
88 | if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) { | ||
71 | printk(KERN_DEBUG "%s: entries remaining in delayed crypt " | 89 | printk(KERN_DEBUG "%s: entries remaining in delayed crypt " |
72 | "deletion list\n", ieee->dev->name); | 90 | "deletion list\n", ieee->dev->name); |
73 | ieee->crypt_deinit_timer.expires = jiffies + HZ; | 91 | ieee->crypt_deinit_timer.expires = jiffies + HZ; |
74 | add_timer(&ieee->crypt_deinit_timer); | 92 | add_timer(&ieee->crypt_deinit_timer); |
75 | } | 93 | } |
76 | 94 | spin_unlock_irqrestore(&ieee->lock, flags); | |
77 | } | 95 | } |
78 | 96 | ||
79 | void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, | 97 | void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, |
@@ -93,10 +111,12 @@ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, | |||
93 | * locking. */ | 111 | * locking. */ |
94 | 112 | ||
95 | spin_lock_irqsave(&ieee->lock, flags); | 113 | spin_lock_irqsave(&ieee->lock, flags); |
96 | list_add(&tmp->list, &ieee->crypt_deinit_list); | 114 | if (!ieee->crypt_quiesced) { |
97 | if (!timer_pending(&ieee->crypt_deinit_timer)) { | 115 | list_add(&tmp->list, &ieee->crypt_deinit_list); |
98 | ieee->crypt_deinit_timer.expires = jiffies + HZ; | 116 | if (!timer_pending(&ieee->crypt_deinit_timer)) { |
99 | add_timer(&ieee->crypt_deinit_timer); | 117 | ieee->crypt_deinit_timer.expires = jiffies + HZ; |
118 | add_timer(&ieee->crypt_deinit_timer); | ||
119 | } | ||
100 | } | 120 | } |
101 | spin_unlock_irqrestore(&ieee->lock, flags); | 121 | spin_unlock_irqrestore(&ieee->lock, flags); |
102 | } | 122 | } |
@@ -250,6 +270,7 @@ static void __exit ieee80211_crypto_deinit(void) | |||
250 | EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); | 270 | EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); |
251 | EXPORT_SYMBOL(ieee80211_crypt_deinit_handler); | 271 | EXPORT_SYMBOL(ieee80211_crypt_deinit_handler); |
252 | EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit); | 272 | EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit); |
273 | EXPORT_SYMBOL(ieee80211_crypt_quiescing); | ||
253 | 274 | ||
254 | EXPORT_SYMBOL(ieee80211_register_crypto_ops); | 275 | EXPORT_SYMBOL(ieee80211_register_crypto_ops); |
255 | EXPORT_SYMBOL(ieee80211_unregister_crypto_ops); | 276 | EXPORT_SYMBOL(ieee80211_unregister_crypto_ops); |