diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2010-12-13 06:36:18 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-12-13 15:23:36 -0500 |
commit | dba5dc1ae9764902f46d5225c9ff40e4f7b614c7 (patch) | |
tree | 693be19fa299bad11310e394fb06c0d4effb898b /drivers/net/wireless/rt2x00/rt2x00usb.c | |
parent | 64e7d72384c2ecef5a892b2243623af265dd83cc (diff) |
rt2x00: Introduce extra queue entry sanity flag
Add a queue entry flag ENTRY_DATA_STATUS_PENDING,
which can be used to indicate a queue entry has
returned from the hardware and is waiting for
status processing. Using this flag we can add
some extra sanity checks to prevent queue corruption.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Acked-by: Helmut Schaa <helmut.schaa@googlemail.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 | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index cd29ebc8a37b..8a16b5106a33 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -195,7 +195,8 @@ static void rt2x00usb_work_txdone(struct work_struct *work) | |||
195 | while (!rt2x00queue_empty(queue)) { | 195 | while (!rt2x00queue_empty(queue)) { |
196 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | 196 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
197 | 197 | ||
198 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | 198 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
199 | !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) | ||
199 | break; | 200 | break; |
200 | 201 | ||
201 | rt2x00usb_work_txdone_entry(entry); | 202 | rt2x00usb_work_txdone_entry(entry); |
@@ -237,7 +238,8 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) | |||
237 | u32 length; | 238 | u32 length; |
238 | int status; | 239 | int status; |
239 | 240 | ||
240 | if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) | 241 | if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) || |
242 | test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) | ||
241 | return; | 243 | return; |
242 | 244 | ||
243 | /* | 245 | /* |
@@ -275,7 +277,8 @@ static void rt2x00usb_work_rxdone(struct work_struct *work) | |||
275 | while (!rt2x00queue_empty(rt2x00dev->rx)) { | 277 | while (!rt2x00queue_empty(rt2x00dev->rx)) { |
276 | entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE); | 278 | entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE); |
277 | 279 | ||
278 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | 280 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
281 | !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) | ||
279 | break; | 282 | break; |
280 | 283 | ||
281 | /* | 284 | /* |
@@ -327,7 +330,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) | |||
327 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 330 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
328 | int status; | 331 | int status; |
329 | 332 | ||
330 | if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | 333 | if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
334 | test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) | ||
331 | return; | 335 | return; |
332 | 336 | ||
333 | rt2x00lib_dmastart(entry); | 337 | rt2x00lib_dmastart(entry); |