Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 070192dd authored by Ivo van Doorn's avatar Ivo van Doorn Committed by John W. Linville
Browse files

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: default avatarIvo van Doorn <IvDoorn@gmail.com>
Acked-by: default avatarGertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 303c7d6a
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -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:
	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);
	rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
	}
}
EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);

+2 −6
Original line number Diff line number Diff line
@@ -226,8 +226,6 @@ 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);
}

@@ -409,8 +407,6 @@ 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);
}