aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2010-11-04 15:41:05 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-11-15 13:26:07 -0500
commit070192dd2975c0e97bbdeac7623b755235c6db7d (patch)
treee7720e75b93f08fe5f3c37a87b26f75b483ca97b
parent303c7d6abfd0430e39e84a43361492b4a8c890b6 (diff)
rt2x00: Fix crash on USB unplug
By not scheduling the TX/RX completion worker threads when Radio is disabled, or hardware has been unplugged, the queues cannot be completely cleaned. This causes crashes when the hardware has been unplugged while the radio is still enabled. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Acked-by: Gertjan van Wingerde <gwingerde@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c8
2 files changed, 12 insertions, 8 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 5ba79b935f09..0f34d996975b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -483,6 +483,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry)
483 unsigned int header_length; 483 unsigned int header_length;
484 int rate_idx; 484 int rate_idx;
485 485
486 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
487 !test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
488 goto submit_entry;
489
486 if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) 490 if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
487 goto submit_entry; 491 goto submit_entry;
488 492
@@ -567,9 +571,13 @@ void rt2x00lib_rxdone(struct queue_entry *entry)
567 entry->skb = skb; 571 entry->skb = skb;
568 572
569submit_entry: 573submit_entry:
570 rt2x00dev->ops->lib->clear_entry(entry); 574 entry->flags = 0;
571 rt2x00queue_index_inc(entry->queue, Q_INDEX);
572 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); 575 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
576 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
577 test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
578 rt2x00dev->ops->lib->clear_entry(entry);
579 rt2x00queue_index_inc(entry->queue, Q_INDEX);
580 }
573} 581}
574EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); 582EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
575 583
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 6dd96192dd91..9ac14598e2a0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -226,9 +226,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
226 * Schedule the delayed work for reading the TX status 226 * Schedule the delayed work for reading the TX status
227 * from the device. 227 * from the device.
228 */ 228 */
229 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && 229 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
230 test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
231 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
232} 230}
233 231
234static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) 232static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
@@ -409,9 +407,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
409 * Schedule the delayed work for reading the RX status 407 * Schedule the delayed work for reading the RX status
410 * from the device. 408 * from the device.
411 */ 409 */
412 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && 410 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
413 test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
414 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
415} 411}
416 412
417/* 413/*