aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c12
3 files changed, 14 insertions, 5 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 3d4c61fcf06f..fa74acdd271f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -235,6 +235,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_dmastart);
235 235
236void rt2x00lib_dmadone(struct queue_entry *entry) 236void rt2x00lib_dmadone(struct queue_entry *entry)
237{ 237{
238 set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);
238 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 239 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
239 rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); 240 rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
240} 241}
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index baa39b75430c..47659346070b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -340,12 +340,16 @@ struct txentry_desc {
340 * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured 340 * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured
341 * while transfering the data to the hardware. No TX status report will 341 * while transfering the data to the hardware. No TX status report will
342 * be expected from the hardware. 342 * be expected from the hardware.
343 * @ENTRY_DATA_STATUS_PENDING: The entry has been send to the device and
344 * returned. It is now waiting for the status reporting before the
345 * entry can be reused again.
343 */ 346 */
344enum queue_entry_flags { 347enum queue_entry_flags {
345 ENTRY_BCN_ASSIGNED, 348 ENTRY_BCN_ASSIGNED,
346 ENTRY_OWNER_DEVICE_DATA, 349 ENTRY_OWNER_DEVICE_DATA,
347 ENTRY_DATA_PENDING, 350 ENTRY_DATA_PENDING,
348 ENTRY_DATA_IO_FAILED 351 ENTRY_DATA_IO_FAILED,
352 ENTRY_DATA_STATUS_PENDING,
349}; 353};
350 354
351/** 355/**
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);