diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800usb.c')
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 20 | 
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 939563162fb..dbf501ca317 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -464,6 +464,15 @@ static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)  	int wcid, ack, pid;  	int tx_wcid, tx_ack, tx_pid; +	if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || +	    !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) { +		WARNING(entry->queue->rt2x00dev, +			"Data pending for entry %u in queue %u\n", +			entry->entry_idx, entry->queue->qid); +		cond_resched(); +		return false; +	} +  	wcid	= rt2x00_get_field32(reg, TX_STA_FIFO_WCID);  	ack	= rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);  	pid	= rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); @@ -529,12 +538,11 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)  			entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);  			if (rt2800usb_txdone_entry_check(entry, reg))  				break; +			entry = NULL;  		} -		if (!entry || rt2x00queue_empty(queue)) -			break; - -		rt2800_txdone_entry(entry, reg); +		if (entry) +			rt2800_txdone_entry(entry, reg);  	}  } @@ -558,8 +566,10 @@ static void rt2800usb_work_txdone(struct work_struct *work)  		while (!rt2x00queue_empty(queue)) {  			entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); -			if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) +			if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || +			    !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))  				break; +  			if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))  				rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);  			else if (rt2x00queue_status_timeout(entry))  |