Commit 10e11568 authored by Helmut Schaa's avatar Helmut Schaa Committed by John W. Linville

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: default avatarHelmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Acked-by: default avatarGertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 7dab73b3
...@@ -650,10 +650,12 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, ...@@ -650,10 +650,12 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
return ret; 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 start,
enum queue_index end, enum queue_index end,
void (*fn)(struct queue_entry *entry)) void *data,
bool (*fn)(struct queue_entry *entry,
void *data))
{ {
unsigned long irqflags; unsigned long irqflags;
unsigned int index_start; unsigned int index_start;
...@@ -664,7 +666,7 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, ...@@ -664,7 +666,7 @@ void rt2x00queue_for_each_entry(struct data_queue *queue,
ERROR(queue->rt2x00dev, ERROR(queue->rt2x00dev,
"Entry requested from invalid index range (%d - %d)\n", "Entry requested from invalid index range (%d - %d)\n",
start, end); start, end);
return; return true;
} }
/* /*
...@@ -683,15 +685,23 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, ...@@ -683,15 +685,23 @@ void rt2x00queue_for_each_entry(struct data_queue *queue,
* send out all frames in the correct order. * send out all frames in the correct order.
*/ */
if (index_start < index_end) { if (index_start < index_end) {
for (i = index_start; i < index_end; i++) for (i = index_start; i < index_end; i++) {
fn(&queue->entries[i]); if (fn(&queue->entries[i], data))
return true;
}
} else { } else {
for (i = index_start; i < queue->limit; i++) for (i = index_start; i < queue->limit; i++) {
fn(&queue->entries[i]); if (fn(&queue->entries[i], data))
return true;
}
for (i = 0; i < index_end; i++) for (i = 0; i < index_end; i++) {
fn(&queue->entries[i]); if (fn(&queue->entries[i], data))
return true;
}
} }
return false;
} }
EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry);
......
...@@ -580,16 +580,22 @@ struct data_queue_desc { ...@@ -580,16 +580,22 @@ struct data_queue_desc {
* @queue: Pointer to @data_queue * @queue: Pointer to @data_queue
* @start: &enum queue_index Pointer to start index * @start: &enum queue_index Pointer to start index
* @end: &enum queue_index Pointer to end 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 * @fn: The function to call for each &struct queue_entry
* *
* This will walk through all entries in the queue, in chronological * This will walk through all entries in the queue, in chronological
* order. This means it will start at the current @start pointer * order. This means it will start at the current @start pointer
* and will walk through the queue until it reaches the @end 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 start,
enum queue_index end, 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. * rt2x00queue_empty - Check if the queue is empty.
......
...@@ -230,7 +230,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) ...@@ -230,7 +230,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); 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 rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 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) ...@@ -240,7 +240,7 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
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)) test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
return; return true;
/* /*
* USB devices cannot blindly pass the skb->len as the * USB devices cannot blindly pass the skb->len as the
...@@ -261,6 +261,8 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) ...@@ -261,6 +261,8 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
rt2x00lib_dmadone(entry); rt2x00lib_dmadone(entry);
} }
return false;
} }
/* /*
...@@ -323,7 +325,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) ...@@ -323,7 +325,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work); 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 rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 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) ...@@ -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) || if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
return; return true;
rt2x00lib_dmastart(entry); rt2x00lib_dmastart(entry);
...@@ -348,6 +350,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) ...@@ -348,6 +350,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
rt2x00lib_dmadone(entry); rt2x00lib_dmadone(entry);
} }
return false;
} }
void rt2x00usb_kick_queue(struct data_queue *queue) void rt2x00usb_kick_queue(struct data_queue *queue)
...@@ -358,12 +362,18 @@ 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_BE:
case QID_AC_BK: case QID_AC_BK:
if (!rt2x00queue_empty(queue)) 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); rt2x00usb_kick_tx_entry);
break; break;
case QID_RX: case QID_RX:
if (!rt2x00queue_full(queue)) 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); rt2x00usb_kick_rx_entry);
break; break;
default: default:
...@@ -372,14 +382,14 @@ void rt2x00usb_kick_queue(struct data_queue *queue) ...@@ -372,14 +382,14 @@ void rt2x00usb_kick_queue(struct data_queue *queue)
} }
EXPORT_SYMBOL_GPL(rt2x00usb_kick_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 rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct queue_entry_priv_usb *entry_priv = entry->priv_data; struct queue_entry_priv_usb *entry_priv = entry->priv_data;
struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return; return true;
usb_kill_urb(entry_priv->urb); usb_kill_urb(entry_priv->urb);
...@@ -389,6 +399,8 @@ static void rt2x00usb_flush_entry(struct queue_entry *entry) ...@@ -389,6 +399,8 @@ static void rt2x00usb_flush_entry(struct queue_entry *entry)
if ((entry->queue->qid == QID_BEACON) && if ((entry->queue->qid == QID_BEACON) &&
(test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags))) (test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)))
usb_kill_urb(bcn_priv->guardian_urb); usb_kill_urb(bcn_priv->guardian_urb);
return false;
} }
void rt2x00usb_flush_queue(struct data_queue *queue) void rt2x00usb_flush_queue(struct data_queue *queue)
...@@ -396,7 +408,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue) ...@@ -396,7 +408,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue)
struct work_struct *completion; struct work_struct *completion;
unsigned int i; 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); rt2x00usb_flush_entry);
/* /*
...@@ -489,7 +501,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) ...@@ -489,7 +501,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
entry->flags = 0; entry->flags = 0;
if (entry->queue->qid == QID_RX) if (entry->queue->qid == QID_RX)
rt2x00usb_kick_rx_entry(entry); rt2x00usb_kick_rx_entry(entry, NULL);
} }
EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment