rt2x00: Introduce extra queue entry sanity flag
Add a queue entry flag ENTRY_DATA_STATUS_PENDING, which can be used to indicate a queue entry has returned from the hardware and is waiting for status processing. Using this flag we can add some extra sanity checks to prevent queue corruption. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Acked-by: Helmut Schaa <helmut.schaa@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
64e7d72384
commit
dba5dc1ae9
@ -235,6 +235,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_dmastart);
|
|||||||
|
|
||||||
void rt2x00lib_dmadone(struct queue_entry *entry)
|
void rt2x00lib_dmadone(struct queue_entry *entry)
|
||||||
{
|
{
|
||||||
|
set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);
|
||||||
clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
|
clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
|
||||||
rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
|
rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
|
||||||
}
|
}
|
||||||
|
@ -340,12 +340,16 @@ struct txentry_desc {
|
|||||||
* @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured
|
* @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured
|
||||||
* while transfering the data to the hardware. No TX status report will
|
* while transfering the data to the hardware. No TX status report will
|
||||||
* be expected from the hardware.
|
* be expected from the hardware.
|
||||||
|
* @ENTRY_DATA_STATUS_PENDING: The entry has been send to the device and
|
||||||
|
* returned. It is now waiting for the status reporting before the
|
||||||
|
* entry can be reused again.
|
||||||
*/
|
*/
|
||||||
enum queue_entry_flags {
|
enum queue_entry_flags {
|
||||||
ENTRY_BCN_ASSIGNED,
|
ENTRY_BCN_ASSIGNED,
|
||||||
ENTRY_OWNER_DEVICE_DATA,
|
ENTRY_OWNER_DEVICE_DATA,
|
||||||
ENTRY_DATA_PENDING,
|
ENTRY_DATA_PENDING,
|
||||||
ENTRY_DATA_IO_FAILED
|
ENTRY_DATA_IO_FAILED,
|
||||||
|
ENTRY_DATA_STATUS_PENDING,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -195,7 +195,8 @@ static void rt2x00usb_work_txdone(struct work_struct *work)
|
|||||||
while (!rt2x00queue_empty(queue)) {
|
while (!rt2x00queue_empty(queue)) {
|
||||||
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
|
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;
|
break;
|
||||||
|
|
||||||
rt2x00usb_work_txdone_entry(entry);
|
rt2x00usb_work_txdone_entry(entry);
|
||||||
@ -237,7 +238,8 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
|
|||||||
u32 length;
|
u32 length;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
|
if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) ||
|
||||||
|
test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -275,7 +277,8 @@ static void rt2x00usb_work_rxdone(struct work_struct *work)
|
|||||||
while (!rt2x00queue_empty(rt2x00dev->rx)) {
|
while (!rt2x00queue_empty(rt2x00dev->rx)) {
|
||||||
entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE);
|
entry = rt2x00queue_get_entry(rt2x00dev->rx, 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;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -327,7 +330,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
|
|||||||
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
|
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
|
if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
|
||||||
|
test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rt2x00lib_dmastart(entry);
|
rt2x00lib_dmastart(entry);
|
||||||
|
Loading…
Reference in New Issue
Block a user