rt2x00: fix queue timeout checks

Add a timestamp to each queue entry which is updated whenever
the status of the entry changes, and remove the per-queue
timestamps.  The previous check was incorrect and caused both
false positives and false negatives.

With the corrected check it comes apparent that the TX status
usually times out on rt2800usb unless there is sufficient traffic
(i.e. the next TX will complete the previous TX status).

Signed-off-by: Johannes Stezenbach <js@sig21.net>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Johannes Stezenbach
2011-04-18 15:29:38 +02:00
committed by John W. Linville
parent 0e0d39e5f3
commit 75256f0348
5 changed files with 43 additions and 25 deletions

View File

@@ -521,15 +521,31 @@ static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work);
}
static int rt2x00usb_status_timeout(struct data_queue *queue)
{
struct queue_entry *entry;
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
return rt2x00queue_status_timeout(entry);
}
static int rt2x00usb_dma_timeout(struct data_queue *queue)
{
struct queue_entry *entry;
entry = rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE);
return rt2x00queue_dma_timeout(entry);
}
void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
tx_queue_for_each(rt2x00dev, queue) {
if (!rt2x00queue_empty(queue)) {
if (rt2x00queue_dma_timeout(queue))
if (rt2x00usb_dma_timeout(queue))
rt2x00usb_watchdog_tx_dma(queue);
if (rt2x00queue_status_timeout(queue))
if (rt2x00usb_status_timeout(queue))
rt2x00usb_watchdog_tx_status(queue);
}
}