diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2008-08-29 15:04:26 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-08-29 16:24:11 -0400 |
commit | 0262ab0df64a67d4c0ed7577a29b7d866819cc68 (patch) | |
tree | 95c5e7842787c60140fe6c35ff7a1bc8b43bebaf /drivers/net/wireless/rt2x00/rt2x00mac.c | |
parent | de9cc7a4e6f975ca5e91cf8745b3e35a7e780bae (diff) |
rt2x00: Fix race conditions in flag handling
Some of the flags should be accessed atomically to
prevent race conditions. The flags that are most important
are those that can change often and indicate the actual
state of the device, queue or queue entry.
The big flag rename was done to move all state flags to
the same naming type as the other rt2x00dev flags and
made sure all places where the flags were used were changed. ;)
Thanks to Stephen for most of the queue flags updates,
which fixes some of the most obvious consequences of the
race conditions. Among those the notorious:
rt2x00queue_write_tx_frame: Error - Arrived at non-free entry in the non-full queue 0.
rt2x00queue_write_tx_frame: Error - Arrived at non-free entry in the non-full queue 0.
rt2x00queue_write_tx_frame: Error - Arrived at non-free entry in the non-full queue 0.
Signed-off-by: Stephen Blackheath <tramp.enshrine.stephen@blacksapphire.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00mac.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 3af427339417..11be8957b5c2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -117,7 +117,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
117 | * Note that we can only stop the TX queues inside the TX path | 117 | * Note that we can only stop the TX queues inside the TX path |
118 | * due to possible race conditions in mac80211. | 118 | * due to possible race conditions in mac80211. |
119 | */ | 119 | */ |
120 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) | 120 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
121 | goto exit_fail; | 121 | goto exit_fail; |
122 | 122 | ||
123 | /* | 123 | /* |
@@ -175,7 +175,7 @@ int rt2x00mac_start(struct ieee80211_hw *hw) | |||
175 | { | 175 | { |
176 | struct rt2x00_dev *rt2x00dev = hw->priv; | 176 | struct rt2x00_dev *rt2x00dev = hw->priv; |
177 | 177 | ||
178 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) | 178 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
179 | return 0; | 179 | return 0; |
180 | 180 | ||
181 | return rt2x00lib_start(rt2x00dev); | 181 | return rt2x00lib_start(rt2x00dev); |
@@ -186,7 +186,7 @@ void rt2x00mac_stop(struct ieee80211_hw *hw) | |||
186 | { | 186 | { |
187 | struct rt2x00_dev *rt2x00dev = hw->priv; | 187 | struct rt2x00_dev *rt2x00dev = hw->priv; |
188 | 188 | ||
189 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) | 189 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
190 | return; | 190 | return; |
191 | 191 | ||
192 | rt2x00lib_stop(rt2x00dev); | 192 | rt2x00lib_stop(rt2x00dev); |
@@ -206,8 +206,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
206 | * Don't allow interfaces to be added | 206 | * Don't allow interfaces to be added |
207 | * the device has disappeared. | 207 | * the device has disappeared. |
208 | */ | 208 | */ |
209 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || | 209 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || |
210 | !test_bit(DEVICE_STARTED, &rt2x00dev->flags)) | 210 | !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) |
211 | return -ENODEV; | 211 | return -ENODEV; |
212 | 212 | ||
213 | switch (conf->type) { | 213 | switch (conf->type) { |
@@ -256,7 +256,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
256 | */ | 256 | */ |
257 | for (i = 0; i < queue->limit; i++) { | 257 | for (i = 0; i < queue->limit; i++) { |
258 | entry = &queue->entries[i]; | 258 | entry = &queue->entries[i]; |
259 | if (!__test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags)) | 259 | if (!test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags)) |
260 | break; | 260 | break; |
261 | } | 261 | } |
262 | 262 | ||
@@ -310,7 +310,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | |||
310 | * either the device has disappeared or when | 310 | * either the device has disappeared or when |
311 | * no interface is present. | 311 | * no interface is present. |
312 | */ | 312 | */ |
313 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || | 313 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || |
314 | (conf->type == IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_ap_count) || | 314 | (conf->type == IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_ap_count) || |
315 | (conf->type != IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_sta_count)) | 315 | (conf->type != IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_sta_count)) |
316 | return; | 316 | return; |
@@ -324,7 +324,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | |||
324 | * Release beacon entry so it is available for | 324 | * Release beacon entry so it is available for |
325 | * new interfaces again. | 325 | * new interfaces again. |
326 | */ | 326 | */ |
327 | __clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags); | 327 | clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags); |
328 | 328 | ||
329 | /* | 329 | /* |
330 | * Make sure the bssid and mac address registers | 330 | * Make sure the bssid and mac address registers |
@@ -344,14 +344,14 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | |||
344 | * Mac80211 might be calling this function while we are trying | 344 | * Mac80211 might be calling this function while we are trying |
345 | * to remove the device or perhaps suspending it. | 345 | * to remove the device or perhaps suspending it. |
346 | */ | 346 | */ |
347 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) | 347 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
348 | return 0; | 348 | return 0; |
349 | 349 | ||
350 | /* | 350 | /* |
351 | * Check if we need to disable the radio, | 351 | * Check if we need to disable the radio, |
352 | * if this is not the case, at least the RX must be disabled. | 352 | * if this is not the case, at least the RX must be disabled. |
353 | */ | 353 | */ |
354 | if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) { | 354 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { |
355 | if (!conf->radio_enabled) | 355 | if (!conf->radio_enabled) |
356 | rt2x00lib_disable_radio(rt2x00dev); | 356 | rt2x00lib_disable_radio(rt2x00dev); |
357 | else | 357 | else |
@@ -366,14 +366,14 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | |||
366 | * initialized. | 366 | * initialized. |
367 | */ | 367 | */ |
368 | force_reconfig = | 368 | force_reconfig = |
369 | __test_and_clear_bit(DEVICE_DIRTY_CONFIG, &rt2x00dev->flags); | 369 | test_and_clear_bit(DEVICE_STATE_DIRTY_CONFIG, &rt2x00dev->flags); |
370 | 370 | ||
371 | rt2x00lib_config(rt2x00dev, conf, force_reconfig); | 371 | rt2x00lib_config(rt2x00dev, conf, force_reconfig); |
372 | 372 | ||
373 | /* | 373 | /* |
374 | * Reenable RX only if the radio should be on. | 374 | * Reenable RX only if the radio should be on. |
375 | */ | 375 | */ |
376 | if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 376 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
377 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); | 377 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); |
378 | else if (conf->radio_enabled) | 378 | else if (conf->radio_enabled) |
379 | return rt2x00lib_enable_radio(rt2x00dev); | 379 | return rt2x00lib_enable_radio(rt2x00dev); |
@@ -395,7 +395,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
395 | * Mac80211 might be calling this function while we are trying | 395 | * Mac80211 might be calling this function while we are trying |
396 | * to remove the device or perhaps suspending it. | 396 | * to remove the device or perhaps suspending it. |
397 | */ | 397 | */ |
398 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) | 398 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
399 | return 0; | 399 | return 0; |
400 | 400 | ||
401 | spin_lock(&intf->lock); | 401 | spin_lock(&intf->lock); |