aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00usb.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2010-12-13 06:36:18 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-12-13 15:23:36 -0500
commitdba5dc1ae9764902f46d5225c9ff40e4f7b614c7 (patch)
tree693be19fa299bad11310e394fb06c0d4effb898b /drivers/net/wireless/rt2x00/rt2x00usb.c
parent64e7d72384c2ecef5a892b2243623af265dd83cc (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.c12
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);