rt2x00: do not pause queue on flush
Pausing queue on flush make no sense since txdone procedure un-pause queue. Before flush procedure we have to assure queue is stopped, i.e. on receive path h/w RX is disabled, on transmit path queue is disabled in mac80211. That conditions are true except one function: rt2x00usb_watchdog_tx_dma(), so add stop/start queue there. Note stop/start queue can be racy if we do this from multiple paths, but currently we stop TX queues only on rt2x00lib_disable_radio(), which also stop/sync watchdog, hance we have no race condition. Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
committed by
John W. Linville
parent
733aec6a5b
commit
fdbdd25c47
@@ -1033,38 +1033,21 @@ EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue);
|
|||||||
|
|
||||||
void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
|
void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
|
||||||
{
|
{
|
||||||
bool started;
|
|
||||||
bool tx_queue =
|
bool tx_queue =
|
||||||
(queue->qid == QID_AC_VO) ||
|
(queue->qid == QID_AC_VO) ||
|
||||||
(queue->qid == QID_AC_VI) ||
|
(queue->qid == QID_AC_VI) ||
|
||||||
(queue->qid == QID_AC_BE) ||
|
(queue->qid == QID_AC_BE) ||
|
||||||
(queue->qid == QID_AC_BK);
|
(queue->qid == QID_AC_BK);
|
||||||
|
|
||||||
mutex_lock(&queue->status_lock);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the queue has been started, we must stop it temporarily
|
* If we are not supposed to drop any pending
|
||||||
* to prevent any new frames to be queued on the device. If
|
* frames, this means we must force a start (=kick)
|
||||||
* we are not dropping the pending frames, the queue must
|
* to the queue to make sure the hardware will
|
||||||
* only be stopped in the software and not the hardware,
|
* start transmitting.
|
||||||
* otherwise the queue will never become empty on its own.
|
|
||||||
*/
|
*/
|
||||||
started = test_bit(QUEUE_STARTED, &queue->flags);
|
if (!drop && tx_queue)
|
||||||
if (started) {
|
queue->rt2x00dev->ops->lib->kick_queue(queue);
|
||||||
/*
|
|
||||||
* Pause the queue
|
|
||||||
*/
|
|
||||||
rt2x00queue_pause_queue(queue);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we are not supposed to drop any pending
|
|
||||||
* frames, this means we must force a start (=kick)
|
|
||||||
* to the queue to make sure the hardware will
|
|
||||||
* start transmitting.
|
|
||||||
*/
|
|
||||||
if (!drop && tx_queue)
|
|
||||||
queue->rt2x00dev->ops->lib->kick_queue(queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if driver supports flushing, if that is the case we can
|
* Check if driver supports flushing, if that is the case we can
|
||||||
@@ -1080,14 +1063,6 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
|
|||||||
if (unlikely(!rt2x00queue_empty(queue)))
|
if (unlikely(!rt2x00queue_empty(queue)))
|
||||||
rt2x00_warn(queue->rt2x00dev, "Queue %d failed to flush\n",
|
rt2x00_warn(queue->rt2x00dev, "Queue %d failed to flush\n",
|
||||||
queue->qid);
|
queue->qid);
|
||||||
|
|
||||||
/*
|
|
||||||
* Restore the queue to the previous status
|
|
||||||
*/
|
|
||||||
if (started)
|
|
||||||
rt2x00queue_unpause_queue(queue);
|
|
||||||
|
|
||||||
mutex_unlock(&queue->status_lock);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue);
|
EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue);
|
||||||
|
|
||||||
|
@@ -523,7 +523,9 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
|
|||||||
rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced forced reset\n",
|
rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced forced reset\n",
|
||||||
queue->qid);
|
queue->qid);
|
||||||
|
|
||||||
|
rt2x00queue_stop_queue(queue);
|
||||||
rt2x00queue_flush_queue(queue, true);
|
rt2x00queue_flush_queue(queue, true);
|
||||||
|
rt2x00queue_start_queue(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rt2x00usb_dma_timeout(struct data_queue *queue)
|
static int rt2x00usb_dma_timeout(struct data_queue *queue)
|
||||||
|
Reference in New Issue
Block a user