rt2x00: Make rt2x00_queue_entry_for_each more flexible
Allow passing a void pointer to rt2x00_queue_entry_for_each which in turn in provided to the callback function. Furthermore, allow the callback function to stop processing by returning true. And also notify the caller of rt2x00_queue_entry_for_each if the loop was canceled by the callback. No functional changes, just preparation for an upcoming patch. Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Acked-by: Gertjan van Wingerde <gwingerde@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
7dab73b37f
commit
10e11568ca
3 changed files with 49 additions and 21 deletions
|
@ -650,10 +650,12 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
void rt2x00queue_for_each_entry(struct data_queue *queue,
|
||||
bool rt2x00queue_for_each_entry(struct data_queue *queue,
|
||||
enum queue_index start,
|
||||
enum queue_index end,
|
||||
void (*fn)(struct queue_entry *entry))
|
||||
void *data,
|
||||
bool (*fn)(struct queue_entry *entry,
|
||||
void *data))
|
||||
{
|
||||
unsigned long irqflags;
|
||||
unsigned int index_start;
|
||||
|
@ -664,7 +666,7 @@ void rt2x00queue_for_each_entry(struct data_queue *queue,
|
|||
ERROR(queue->rt2x00dev,
|
||||
"Entry requested from invalid index range (%d - %d)\n",
|
||||
start, end);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -683,15 +685,23 @@ void rt2x00queue_for_each_entry(struct data_queue *queue,
|
|||
* send out all frames in the correct order.
|
||||
*/
|
||||
if (index_start < index_end) {
|
||||
for (i = index_start; i < index_end; i++)
|
||||
fn(&queue->entries[i]);
|
||||
for (i = index_start; i < index_end; i++) {
|
||||
if (fn(&queue->entries[i], data))
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
for (i = index_start; i < queue->limit; i++)
|
||||
fn(&queue->entries[i]);
|
||||
for (i = index_start; i < queue->limit; i++) {
|
||||
if (fn(&queue->entries[i], data))
|
||||
return true;
|
||||
}
|
||||
|
||||
for (i = 0; i < index_end; i++)
|
||||
fn(&queue->entries[i]);
|
||||
for (i = 0; i < index_end; i++) {
|
||||
if (fn(&queue->entries[i], data))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry);
|
||||
|
||||
|
|
|
@ -580,16 +580,22 @@ struct data_queue_desc {
|
|||
* @queue: Pointer to @data_queue
|
||||
* @start: &enum queue_index Pointer to start index
|
||||
* @end: &enum queue_index Pointer to end index
|
||||
* @data: Data to pass to the callback function
|
||||
* @fn: The function to call for each &struct queue_entry
|
||||
*
|
||||
* This will walk through all entries in the queue, in chronological
|
||||
* order. This means it will start at the current @start pointer
|
||||
* and will walk through the queue until it reaches the @end pointer.
|
||||
*
|
||||
* If fn returns true for an entry rt2x00queue_for_each_entry will stop
|
||||
* processing and return true as well.
|
||||
*/
|
||||
void rt2x00queue_for_each_entry(struct data_queue *queue,
|
||||
bool rt2x00queue_for_each_entry(struct data_queue *queue,
|
||||
enum queue_index start,
|
||||
enum queue_index end,
|
||||
void (*fn)(struct queue_entry *entry));
|
||||
void *data,
|
||||
bool (*fn)(struct queue_entry *entry,
|
||||
void *data));
|
||||
|
||||
/**
|
||||
* rt2x00queue_empty - Check if the queue is empty.
|
||||
|
|
|
@ -230,7 +230,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
|
|||
queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
|
||||
}
|
||||
|
||||
static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
|
||||
static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
|
||||
|
@ -240,7 +240,7 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
|
|||
|
||||
if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) ||
|
||||
test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
|
||||
return;
|
||||
return true;
|
||||
|
||||
/*
|
||||
* USB devices cannot blindly pass the skb->len as the
|
||||
|
@ -261,6 +261,8 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
|
|||
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
|
||||
rt2x00lib_dmadone(entry);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -323,7 +325,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
|
|||
queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work);
|
||||
}
|
||||
|
||||
static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
|
||||
static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void* data)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
|
||||
|
@ -332,7 +334,7 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
|
|||
|
||||
if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
|
||||
test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
|
||||
return;
|
||||
return true;
|
||||
|
||||
rt2x00lib_dmastart(entry);
|
||||
|
||||
|
@ -348,6 +350,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
|
|||
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
|
||||
rt2x00lib_dmadone(entry);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void rt2x00usb_kick_queue(struct data_queue *queue)
|
||||
|
@ -358,12 +362,18 @@ void rt2x00usb_kick_queue(struct data_queue *queue)
|
|||
case QID_AC_BE:
|
||||
case QID_AC_BK:
|
||||
if (!rt2x00queue_empty(queue))
|
||||
rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
|
||||
rt2x00queue_for_each_entry(queue,
|
||||
Q_INDEX_DONE,
|
||||
Q_INDEX,
|
||||
NULL,
|
||||
rt2x00usb_kick_tx_entry);
|
||||
break;
|
||||
case QID_RX:
|
||||
if (!rt2x00queue_full(queue))
|
||||
rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
|
||||
rt2x00queue_for_each_entry(queue,
|
||||
Q_INDEX_DONE,
|
||||
Q_INDEX,
|
||||
NULL,
|
||||
rt2x00usb_kick_rx_entry);
|
||||
break;
|
||||
default:
|
||||
|
@ -372,14 +382,14 @@ void rt2x00usb_kick_queue(struct data_queue *queue)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue);
|
||||
|
||||
static void rt2x00usb_flush_entry(struct queue_entry *entry)
|
||||
static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
|
||||
struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
|
||||
|
||||
if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
|
||||
return;
|
||||
return true;
|
||||
|
||||
usb_kill_urb(entry_priv->urb);
|
||||
|
||||
|
@ -389,6 +399,8 @@ static void rt2x00usb_flush_entry(struct queue_entry *entry)
|
|||
if ((entry->queue->qid == QID_BEACON) &&
|
||||
(test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)))
|
||||
usb_kill_urb(bcn_priv->guardian_urb);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void rt2x00usb_flush_queue(struct data_queue *queue)
|
||||
|
@ -396,7 +408,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue)
|
|||
struct work_struct *completion;
|
||||
unsigned int i;
|
||||
|
||||
rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
|
||||
rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL,
|
||||
rt2x00usb_flush_entry);
|
||||
|
||||
/*
|
||||
|
@ -489,7 +501,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
|
|||
entry->flags = 0;
|
||||
|
||||
if (entry->queue->qid == QID_RX)
|
||||
rt2x00usb_kick_rx_entry(entry);
|
||||
rt2x00usb_kick_rx_entry(entry, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
|
||||
|
||||
|
|
Loading…
Reference in a new issue