aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00usb.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/rt2x00usb.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/rt2x00usb.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 2050227ea530..2dd7c830c125 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -163,7 +163,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
163 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 163 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
164 struct txdone_entry_desc txdesc; 164 struct txdone_entry_desc txdesc;
165 165
166 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || 166 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
167 !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 167 !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
168 return; 168 return;
169 169
@@ -232,7 +232,7 @@ static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
232{ 232{
233 struct queue_entry_priv_usb *entry_priv = entry->priv_data; 233 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
234 234
235 if (__test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) 235 if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
236 usb_submit_urb(entry_priv->urb, GFP_ATOMIC); 236 usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
237} 237}
238 238
@@ -283,7 +283,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
283 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 283 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
284 u8 rxd[32]; 284 u8 rxd[32];
285 285
286 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || 286 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
287 !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 287 !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
288 return; 288 return;
289 289
@@ -293,7 +293,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
293 * a problem. 293 * a problem.
294 */ 294 */
295 if (urb->actual_length < entry->queue->desc_size || urb->status) { 295 if (urb->actual_length < entry->queue->desc_size || urb->status) {
296 __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 296 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
297 usb_submit_urb(urb, GFP_ATOMIC); 297 usb_submit_urb(urb, GFP_ATOMIC);
298 return; 298 return;
299 } 299 }
@@ -361,7 +361,7 @@ void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
361 entry->skb->data, entry->skb->len, 361 entry->skb->data, entry->skb->len,
362 rt2x00usb_interrupt_rxdone, entry); 362 rt2x00usb_interrupt_rxdone, entry);
363 363
364 __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 364 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
365 usb_submit_urb(entry_priv->urb, GFP_ATOMIC); 365 usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
366} 366}
367EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); 367EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry);