diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2010-11-04 20:41:05 +0100 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-11-15 13:26:07 -0500 |
commit | 070192dd2975c0e97bbdeac7623b755235c6db7d (patch) | |
tree | e7720e75b93f08fe5f3c37a87b26f75b483ca97b /drivers/net/wireless/rt2x00/rt2x00dev.c | |
parent | 303c7d6abfd0430e39e84a43361492b4a8c890b6 (diff) | |
download | kernel_samsung_smdk4412-070192dd2975c0e97bbdeac7623b755235c6db7d.zip kernel_samsung_smdk4412-070192dd2975c0e97bbdeac7623b755235c6db7d.tar.gz kernel_samsung_smdk4412-070192dd2975c0e97bbdeac7623b755235c6db7d.tar.bz2 |
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>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 5ba79b9..0f34d99 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) unsigned int header_length; int rate_idx; + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || + !test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + goto submit_entry; + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) goto submit_entry; @@ -567,9 +571,13 @@ void rt2x00lib_rxdone(struct queue_entry *entry) entry->skb = skb; submit_entry: - rt2x00dev->ops->lib->clear_entry(entry); - rt2x00queue_index_inc(entry->queue, Q_INDEX); + entry->flags = 0; rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && + test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { + rt2x00dev->ops->lib->clear_entry(entry); + rt2x00queue_index_inc(entry->queue, Q_INDEX); + } } EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); |