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 | |
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>
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 12 |
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 | ||
236 | void rt2x00lib_dmadone(struct queue_entry *entry) | 236 | void 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 | */ |
344 | enum queue_entry_flags { | 347 | enum 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); |