aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00dev.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-08-29 15:04:26 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-29 16:24:11 -0400
commit0262ab0df64a67d4c0ed7577a29b7d866819cc68 (patch)
tree95c5e7842787c60140fe6c35ff7a1bc8b43bebaf /drivers/net/wireless/rt2x00/rt2x00dev.c
parentde9cc7a4e6f975ca5e91cf8745b3e35a7e780bae (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/rt2x00dev.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c58
1 files changed, 30 insertions, 28 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 328ff8bc4c1..330ab77902f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -34,7 +34,7 @@
34 */ 34 */
35void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) 35void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev)
36{ 36{
37 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 37 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
38 return; 38 return;
39 39
40 /* 40 /*
@@ -94,8 +94,8 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
94 * Don't enable the radio twice. 94 * Don't enable the radio twice.
95 * And check if the hardware button has been disabled. 95 * And check if the hardware button has been disabled.
96 */ 96 */
97 if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || 97 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
98 test_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags)) 98 test_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags))
99 return 0; 99 return 0;
100 100
101 /* 101 /*
@@ -117,7 +117,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
117 rt2x00leds_led_radio(rt2x00dev, true); 117 rt2x00leds_led_radio(rt2x00dev, true);
118 rt2x00led_led_activity(rt2x00dev, true); 118 rt2x00led_led_activity(rt2x00dev, true);
119 119
120 __set_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags); 120 set_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);
121 121
122 /* 122 /*
123 * Enable RX. 123 * Enable RX.
@@ -134,7 +134,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
134 134
135void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) 135void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
136{ 136{
137 if (!__test_and_clear_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 137 if (!test_and_clear_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
138 return; 138 return;
139 139
140 /* 140 /*
@@ -354,7 +354,7 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
354 * When the radio is shutting down we should 354 * When the radio is shutting down we should
355 * immediately cease all link tuning. 355 * immediately cease all link tuning.
356 */ 356 */
357 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 357 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
358 return; 358 return;
359 359
360 /* 360 /*
@@ -431,7 +431,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
431 * note that in the spinlock protected area above the delayed_flags 431 * note that in the spinlock protected area above the delayed_flags
432 * have been cleared correctly. 432 * have been cleared correctly.
433 */ 433 */
434 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 434 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
435 return; 435 return;
436 436
437 if (delayed_flags & DELAYED_UPDATE_BEACON) 437 if (delayed_flags & DELAYED_UPDATE_BEACON)
@@ -484,7 +484,7 @@ static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
484 484
485void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) 485void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
486{ 486{
487 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 487 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
488 return; 488 return;
489 489
490 ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, 490 ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw,
@@ -572,7 +572,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
572 572
573 rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry); 573 rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry);
574 574
575 __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 575 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
576 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); 576 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
577 577
578 /* 578 /*
@@ -888,7 +888,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
888 888
889static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev) 889static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev)
890{ 890{
891 if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags)) 891 if (test_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags))
892 ieee80211_unregister_hw(rt2x00dev->hw); 892 ieee80211_unregister_hw(rt2x00dev->hw);
893 893
894 if (likely(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ])) { 894 if (likely(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ])) {
@@ -906,6 +906,9 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
906 struct hw_mode_spec *spec = &rt2x00dev->spec; 906 struct hw_mode_spec *spec = &rt2x00dev->spec;
907 int status; 907 int status;
908 908
909 if (test_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags))
910 return 0;
911
909 /* 912 /*
910 * Initialize HW modes. 913 * Initialize HW modes.
911 */ 914 */
@@ -927,7 +930,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
927 return status; 930 return status;
928 } 931 }
929 932
930 __set_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags); 933 set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags);
931 934
932 return 0; 935 return 0;
933} 936}
@@ -937,7 +940,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
937 */ 940 */
938static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) 941static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
939{ 942{
940 if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) 943 if (!test_and_clear_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags))
941 return; 944 return;
942 945
943 /* 946 /*
@@ -960,7 +963,7 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
960{ 963{
961 int status; 964 int status;
962 965
963 if (test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) 966 if (test_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags))
964 return 0; 967 return 0;
965 968
966 /* 969 /*
@@ -979,7 +982,7 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
979 return status; 982 return status;
980 } 983 }
981 984
982 __set_bit(DEVICE_INITIALIZED, &rt2x00dev->flags); 985 set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags);
983 986
984 /* 987 /*
985 * Register the extra components. 988 * Register the extra components.
@@ -993,7 +996,7 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
993{ 996{
994 int retval; 997 int retval;
995 998
996 if (test_bit(DEVICE_STARTED, &rt2x00dev->flags)) 999 if (test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
997 return 0; 1000 return 0;
998 1001
999 /* 1002 /*
@@ -1024,15 +1027,15 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
1024 rt2x00dev->intf_sta_count = 0; 1027 rt2x00dev->intf_sta_count = 0;
1025 rt2x00dev->intf_associated = 0; 1028 rt2x00dev->intf_associated = 0;
1026 1029
1027 __set_bit(DEVICE_STARTED, &rt2x00dev->flags); 1030 set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags);
1028 __set_bit(DEVICE_DIRTY_CONFIG, &rt2x00dev->flags); 1031 set_bit(DEVICE_STATE_DIRTY_CONFIG, &rt2x00dev->flags);
1029 1032
1030 return 0; 1033 return 0;
1031} 1034}
1032 1035
1033void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev) 1036void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev)
1034{ 1037{
1035 if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags)) 1038 if (!test_and_clear_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
1036 return; 1039 return;
1037 1040
1038 /* 1041 /*
@@ -1044,8 +1047,6 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev)
1044 rt2x00dev->intf_ap_count = 0; 1047 rt2x00dev->intf_ap_count = 0;
1045 rt2x00dev->intf_sta_count = 0; 1048 rt2x00dev->intf_sta_count = 0;
1046 rt2x00dev->intf_associated = 0; 1049 rt2x00dev->intf_associated = 0;
1047
1048 __clear_bit(DEVICE_STARTED, &rt2x00dev->flags);
1049} 1050}
1050 1051
1051/* 1052/*
@@ -1100,7 +1101,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1100 rt2x00rfkill_allocate(rt2x00dev); 1101 rt2x00rfkill_allocate(rt2x00dev);
1101 rt2x00debug_register(rt2x00dev); 1102 rt2x00debug_register(rt2x00dev);
1102 1103
1103 __set_bit(DEVICE_PRESENT, &rt2x00dev->flags); 1104 set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
1104 1105
1105 return 0; 1106 return 0;
1106 1107
@@ -1113,7 +1114,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_probe_dev);
1113 1114
1114void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) 1115void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
1115{ 1116{
1116 __clear_bit(DEVICE_PRESENT, &rt2x00dev->flags); 1117 clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
1117 1118
1118 /* 1119 /*
1119 * Disable radio. 1120 * Disable radio.
@@ -1158,14 +1159,15 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
1158 int retval; 1159 int retval;
1159 1160
1160 NOTICE(rt2x00dev, "Going to sleep.\n"); 1161 NOTICE(rt2x00dev, "Going to sleep.\n");
1161 __clear_bit(DEVICE_PRESENT, &rt2x00dev->flags);
1162 1162
1163 /* 1163 /*
1164 * Only continue if mac80211 has open interfaces. 1164 * Only continue if mac80211 has open interfaces.
1165 */ 1165 */
1166 if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags)) 1166 if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
1167 !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
1167 goto exit; 1168 goto exit;
1168 __set_bit(DEVICE_STARTED_SUSPEND, &rt2x00dev->flags); 1169
1170 set_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags);
1169 1171
1170 /* 1172 /*
1171 * Disable radio. 1173 * Disable radio.
@@ -1237,7 +1239,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
1237 /* 1239 /*
1238 * Only continue if mac80211 had open interfaces. 1240 * Only continue if mac80211 had open interfaces.
1239 */ 1241 */
1240 if (!__test_and_clear_bit(DEVICE_STARTED_SUSPEND, &rt2x00dev->flags)) 1242 if (!test_and_clear_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags))
1241 return 0; 1243 return 0;
1242 1244
1243 /* 1245 /*
@@ -1264,7 +1266,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
1264 /* 1266 /*
1265 * We are ready again to receive requests from mac80211. 1267 * We are ready again to receive requests from mac80211.
1266 */ 1268 */
1267 __set_bit(DEVICE_PRESENT, &rt2x00dev->flags); 1269 set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
1268 1270
1269 /* 1271 /*
1270 * It is possible that during that mac80211 has attempted 1272 * It is possible that during that mac80211 has attempted
@@ -1284,7 +1286,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
1284 return 0; 1286 return 0;
1285 1287
1286exit: 1288exit:
1287 rt2x00lib_disable_radio(rt2x00dev); 1289 rt2x00lib_stop(rt2x00dev);
1288 rt2x00lib_uninitialize(rt2x00dev); 1290 rt2x00lib_uninitialize(rt2x00dev);
1289 rt2x00debug_deregister(rt2x00dev); 1291 rt2x00debug_deregister(rt2x00dev);
1290 1292