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/rt2x00usb.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/rt2x00usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 10 |
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 | } |
367 | EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); | 367 | EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); |