diff options
author | Helmut Schaa <helmut.schaa@googlemail.com> | 2011-04-18 09:27:43 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-04-19 15:39:13 -0400 |
commit | 10e11568ca8b8a15f7478f6a4ceebabcbdba1018 (patch) | |
tree | 9ace4fe0ad5280fc46705aebef9bfa06b7c346ef /drivers/net/wireless/rt2x00 | |
parent | 7dab73b37f5e8885cb73efd25e73861f9b4f0246 (diff) |
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>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 32 |
3 files changed, 49 insertions, 21 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index d03eef28f036..458bb489bc7c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -650,10 +650,12 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | |||
650 | return ret; | 650 | return ret; |
651 | } | 651 | } |
652 | 652 | ||
653 | void rt2x00queue_for_each_entry(struct data_queue *queue, | 653 | bool rt2x00queue_for_each_entry(struct data_queue *queue, |
654 | enum queue_index start, | 654 | enum queue_index start, |
655 | enum queue_index end, | 655 | enum queue_index end, |
656 | void (*fn)(struct queue_entry *entry)) | 656 | void *data, |
657 | bool (*fn)(struct queue_entry *entry, | ||
658 | void *data)) | ||
657 | { | 659 | { |
658 | unsigned long irqflags; | 660 | unsigned long irqflags; |
659 | unsigned int index_start; | 661 | unsigned int index_start; |
@@ -664,7 +666,7 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, | |||
664 | ERROR(queue->rt2x00dev, | 666 | ERROR(queue->rt2x00dev, |
665 | "Entry requested from invalid index range (%d - %d)\n", | 667 | "Entry requested from invalid index range (%d - %d)\n", |
666 | start, end); | 668 | start, end); |
667 | return; | 669 | return true; |
668 | } | 670 | } |
669 | 671 | ||
670 | /* | 672 | /* |
@@ -683,15 +685,23 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, | |||
683 | * send out all frames in the correct order. | 685 | * send out all frames in the correct order. |
684 | */ | 686 | */ |
685 | if (index_start < index_end) { | 687 | if (index_start < index_end) { |
686 | for (i = index_start; i < index_end; i++) | 688 | for (i = index_start; i < index_end; i++) { |
687 | fn(&queue->entries[i]); | 689 | if (fn(&queue->entries[i], data)) |
690 | return true; | ||
691 | } | ||
688 | } else { | 692 | } else { |
689 | for (i = index_start; i < queue->limit; i++) | 693 | for (i = index_start; i < queue->limit; i++) { |
690 | fn(&queue->entries[i]); | 694 | if (fn(&queue->entries[i], data)) |
695 | return true; | ||
696 | } | ||
691 | 697 | ||
692 | for (i = 0; i < index_end; i++) | 698 | for (i = 0; i < index_end; i++) { |
693 | fn(&queue->entries[i]); | 699 | if (fn(&queue->entries[i], data)) |
700 | return true; | ||
701 | } | ||
694 | } | 702 | } |
703 | |||
704 | return false; | ||
695 | } | 705 | } |
696 | EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); | 706 | EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); |
697 | 707 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 6ae820093997..6b664525135d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -580,16 +580,22 @@ struct data_queue_desc { | |||
580 | * @queue: Pointer to @data_queue | 580 | * @queue: Pointer to @data_queue |
581 | * @start: &enum queue_index Pointer to start index | 581 | * @start: &enum queue_index Pointer to start index |
582 | * @end: &enum queue_index Pointer to end index | 582 | * @end: &enum queue_index Pointer to end index |
583 | * @data: Data to pass to the callback function | ||
583 | * @fn: The function to call for each &struct queue_entry | 584 | * @fn: The function to call for each &struct queue_entry |
584 | * | 585 | * |
585 | * This will walk through all entries in the queue, in chronological | 586 | * This will walk through all entries in the queue, in chronological |
586 | * order. This means it will start at the current @start pointer | 587 | * order. This means it will start at the current @start pointer |
587 | * and will walk through the queue until it reaches the @end pointer. | 588 | * and will walk through the queue until it reaches the @end pointer. |
589 | * | ||
590 | * If fn returns true for an entry rt2x00queue_for_each_entry will stop | ||
591 | * processing and return true as well. | ||
588 | */ | 592 | */ |
589 | void rt2x00queue_for_each_entry(struct data_queue *queue, | 593 | bool rt2x00queue_for_each_entry(struct data_queue *queue, |
590 | enum queue_index start, | 594 | enum queue_index start, |
591 | enum queue_index end, | 595 | enum queue_index end, |
592 | void (*fn)(struct queue_entry *entry)); | 596 | void *data, |
597 | bool (*fn)(struct queue_entry *entry, | ||
598 | void *data)); | ||
593 | 599 | ||
594 | /** | 600 | /** |
595 | * rt2x00queue_empty - Check if the queue is empty. | 601 | * rt2x00queue_empty - Check if the queue is empty. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 94047e9b2ec6..0bc8dccd0f0a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -230,7 +230,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
230 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); | 230 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); |
231 | } | 231 | } |
232 | 232 | ||
233 | static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) | 233 | static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data) |
234 | { | 234 | { |
235 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 235 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
236 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | 236 | 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 | 240 | ||
241 | if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) || | 241 | if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) || |
242 | test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) | 242 | test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
243 | return; | 243 | return true; |
244 | 244 | ||
245 | /* | 245 | /* |
246 | * USB devices cannot blindly pass the skb->len as the | 246 | * 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 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); | 261 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
262 | rt2x00lib_dmadone(entry); | 262 | rt2x00lib_dmadone(entry); |
263 | } | 263 | } |
264 | |||
265 | return false; | ||
264 | } | 266 | } |
265 | 267 | ||
266 | /* | 268 | /* |
@@ -323,7 +325,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
323 | queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work); | 325 | queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work); |
324 | } | 326 | } |
325 | 327 | ||
326 | static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) | 328 | static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void* data) |
327 | { | 329 | { |
328 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 330 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
329 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | 331 | 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 | 334 | ||
333 | if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || | 335 | if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
334 | test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) | 336 | test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
335 | return; | 337 | return true; |
336 | 338 | ||
337 | rt2x00lib_dmastart(entry); | 339 | rt2x00lib_dmastart(entry); |
338 | 340 | ||
@@ -348,6 +350,8 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) | |||
348 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); | 350 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
349 | rt2x00lib_dmadone(entry); | 351 | rt2x00lib_dmadone(entry); |
350 | } | 352 | } |
353 | |||
354 | return false; | ||
351 | } | 355 | } |
352 | 356 | ||
353 | void rt2x00usb_kick_queue(struct data_queue *queue) | 357 | void rt2x00usb_kick_queue(struct data_queue *queue) |
@@ -358,12 +362,18 @@ void rt2x00usb_kick_queue(struct data_queue *queue) | |||
358 | case QID_AC_BE: | 362 | case QID_AC_BE: |
359 | case QID_AC_BK: | 363 | case QID_AC_BK: |
360 | if (!rt2x00queue_empty(queue)) | 364 | if (!rt2x00queue_empty(queue)) |
361 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, | 365 | rt2x00queue_for_each_entry(queue, |
366 | Q_INDEX_DONE, | ||
367 | Q_INDEX, | ||
368 | NULL, | ||
362 | rt2x00usb_kick_tx_entry); | 369 | rt2x00usb_kick_tx_entry); |
363 | break; | 370 | break; |
364 | case QID_RX: | 371 | case QID_RX: |
365 | if (!rt2x00queue_full(queue)) | 372 | if (!rt2x00queue_full(queue)) |
366 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, | 373 | rt2x00queue_for_each_entry(queue, |
374 | Q_INDEX_DONE, | ||
375 | Q_INDEX, | ||
376 | NULL, | ||
367 | rt2x00usb_kick_rx_entry); | 377 | rt2x00usb_kick_rx_entry); |
368 | break; | 378 | break; |
369 | default: | 379 | default: |
@@ -372,14 +382,14 @@ void rt2x00usb_kick_queue(struct data_queue *queue) | |||
372 | } | 382 | } |
373 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); | 383 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); |
374 | 384 | ||
375 | static void rt2x00usb_flush_entry(struct queue_entry *entry) | 385 | static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data) |
376 | { | 386 | { |
377 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 387 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
378 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 388 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
379 | struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; | 389 | struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; |
380 | 390 | ||
381 | if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | 391 | if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
382 | return; | 392 | return true; |
383 | 393 | ||
384 | usb_kill_urb(entry_priv->urb); | 394 | usb_kill_urb(entry_priv->urb); |
385 | 395 | ||
@@ -389,6 +399,8 @@ static void rt2x00usb_flush_entry(struct queue_entry *entry) | |||
389 | if ((entry->queue->qid == QID_BEACON) && | 399 | if ((entry->queue->qid == QID_BEACON) && |
390 | (test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags))) | 400 | (test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags))) |
391 | usb_kill_urb(bcn_priv->guardian_urb); | 401 | usb_kill_urb(bcn_priv->guardian_urb); |
402 | |||
403 | return false; | ||
392 | } | 404 | } |
393 | 405 | ||
394 | void rt2x00usb_flush_queue(struct data_queue *queue) | 406 | void rt2x00usb_flush_queue(struct data_queue *queue) |
@@ -396,7 +408,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue) | |||
396 | struct work_struct *completion; | 408 | struct work_struct *completion; |
397 | unsigned int i; | 409 | unsigned int i; |
398 | 410 | ||
399 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, | 411 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL, |
400 | rt2x00usb_flush_entry); | 412 | rt2x00usb_flush_entry); |
401 | 413 | ||
402 | /* | 414 | /* |
@@ -489,7 +501,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) | |||
489 | entry->flags = 0; | 501 | entry->flags = 0; |
490 | 502 | ||
491 | if (entry->queue->qid == QID_RX) | 503 | if (entry->queue->qid == QID_RX) |
492 | rt2x00usb_kick_rx_entry(entry); | 504 | rt2x00usb_kick_rx_entry(entry, NULL); |
493 | } | 505 | } |
494 | EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); | 506 | EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); |
495 | 507 | ||