]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
rt2x00: Fix crash on USB unplug
authorIvo van Doorn <ivdoorn@gmail.com>
Thu, 4 Nov 2010 19:41:05 +0000 (20:41 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 23 Mar 2011 19:49:57 +0000 (12:49 -0700)
commit 070192dd2975c0e97bbdeac7623b755235c6db7d upstream.

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>
Cc: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00usb.c

index d019830ca8407c2aa10ed0ae95abe8679c654e55..06995b29a5226003102cffa13cb20f177d5b6589 100644 (file)
@@ -486,6 +486,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;
 
@@ -570,9 +574,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);
 
index b3317df7a7d4afdd88169c8ad16f2ad99984bc9e..a1084914706219db7208fb61fe7137a1dcbefcd9 100644 (file)
@@ -226,9 +226,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
         * Schedule the delayed work for reading the TX status
         * from the device.
         */
-       if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
-           test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-               ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
+       ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
 }
 
 static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
@@ -424,9 +422,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
         * Schedule the delayed work for reading the RX status
         * from the device.
         */
-       if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
-           test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-               ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
+       ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
 }
 
 /*